4 WaysUp (A Full Length First Person Puzzle Game)

This is a full length, first person puzzle game.
The game took about a year and a half for me to make.

If the video doesn’t work, the link is: http://www.youtube.com/watch?v=mfidYhKcqPg

The download links are below. (Using Google Docs)

Blender File (Guaranteed to work in Blender 2.64)

1280 By 720 32 bit
640 By 480 32 bit
Full HD 32 bit

1280 By 720 64 bit
640 By 480 64 bit
Full HD 64 bit

Blender File (Version 2.64)

Mac Versions Below
Full Screen Full HD 32 bit
Full Screen Full HD 64 bit
Window View 32 bit (use this one if the HD one has a bad frame rate)
Window View 64 bit (use this one if the HD one has a bad frame rate
You will have to extract the zip file.

Please try it and let me know if I need to fix anything.
I also used Lmms, Audasity, Gimp, and MS Paint.

Very impressive! I downloaded the game and love it!

Downloading. Looks pretty neat. Will get back to you when it finishes and I get to try it. :slight_smile:

I would like to explain how the hookshot scripts work in the game because someone asked.
You can download the .blend to get the python script but let me explain it here because it is a bit confusing to read.

  1.   The right mouse button is pressed.
  2.   A ray checks if there is a wall directly in front of the player.
  3.   A timer is checked to see if the ropeshot is still firing.
  4.   An object which is parented to the character and at a position the ropeshot should be firing towards is recording its own x, y, and z position every frame.
  5.   These coordinates are taken from the object and given to the ropeshot spawner (an empty) which has been parented to the character’s wrist.
  6.   The empty subtracts these coordinates with its own coordinates to find the relative direction of the second object.
  7.   Then it sets the character’s velocity equal to this vector.

Steps 6-8 in code
def main():
import bge
cont = bge.logic.getCurrentController()
own = cont.owner

xpart = 2*(own["xshot"]-own["xpos"])
ypart = 2*(own["yshot"]-own["ypos"])
zpart = 2*(own["zshot"]-own["zpos"])
                            // it is times 2 just to make the charicter go faster
own.setLinearVelocity([xpart, ypart, zpart])

8. It sets xshot (target position) and xpos (character position) before the script is run and only gets them once meaning that this script will do the same thing every time it is run for a single ropeshot use. This script is run every frame until the character faces a wall (step 2 above) or the ropeshot times out. This means your character will have the same velocity set every frame.
9. This entire process is run by a timer (but does not need to be) where right clicking sets the time to 0. All other events (spawning the collision free rope object, moving the character, canceling the movement, and deleting the rope) occur at set points in time and canceling the ropeshot (from facing a wall) just skips the timer to the end where it will just keep counting to infinity.

The other hookshot from the second half of the game works by similar mechanics but the reference object is a ball which is launched from the characters wrist and sends its own position when it hits an object. Then the script is run once to propel the character towards the object.

def main():
import bge
import math
from math import sqrt

cont = bge.logic.getCurrentController()
own = cont.owner

xpart = (own["xshot"]-own["xpos"])           //xshot is the position of the ball you launched
ypart = (own["yshot"]-own["ypos"])           //xpos is the character’s position
zpart = (own["zshot"]-own["zpos"])

totalses = sqrt(xpart*xpart+ypart*ypart+2*zpart*zpart)
divadivaden = totalses/35

xside = xpart/divadivaden
yside = ypart/divadivaden
zside = 1.4142*zpart/divadivaden
own.setLinearVelocity([xside, yside, zside])


To fire the ball (which gives its position as xshot) it is deparented from the armature of the character and given a velocity by a motion actuator.
On the first frame of gameplay and after every time the hookshot is used, the ball has its rotation set so it will always fly in the same direction and is parented to the armature (don’t parent it in the editor, this causes problems).

def main():
import bge
cont = bge.logic.getCurrentController()
own = cont.owner
own.localOrientation = [[1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
//this is a random orientation but that doesn’t matter as long as it is always the same orientation
//instead of trying to set this orientation right just adjust the motion actuator
xpos = -.1
ypos = 1 // sorry but I honestly don’t remember why this part works?
zpos = 0 // maybe this executes after it is parented so these are local coordinates.

own.position = (xpos,ypos,zpos)


If you have any questions just ask.