world
This commit is contained in:
parent
789cc334e3
commit
04808a0076
|
@ -21,7 +21,7 @@ module.exports =
|
|||
position: [0,0,0]
|
||||
]
|
||||
create: ->
|
||||
#
|
||||
|
||||
s = world.getSize()
|
||||
|
||||
world.addObjectAtPos(KikiStone(), KikiPos(s.x/2-1, s.y/2+1, 0))
|
||||
|
|
121
coffee/main.coffee
Normal file
121
coffee/main.coffee
Normal file
|
@ -0,0 +1,121 @@
|
|||
|
||||
# 000 000 000 000 000 000
|
||||
# 000 000 000 000 000 000
|
||||
# 0000000 000 0000000 000
|
||||
# 000 000 000 000 000 000
|
||||
# 000 000 000 000 000 000
|
||||
|
||||
Stage = require '/Users/kodi/s/ko/js/area/stage'
|
||||
log = require '/Users/kodi/s/ko/js/tools/log'
|
||||
|
||||
KikiWorld = require './world'
|
||||
|
||||
class Kiki extends Stage
|
||||
|
||||
constructor: (@view) -> super @view
|
||||
|
||||
start: ->
|
||||
|
||||
world = new KikiWorld()
|
||||
log 'hello world'
|
||||
|
||||
@elem = document.createElement 'div'
|
||||
@elem.style.position = 'absolute'
|
||||
@elem.style.top = '0'
|
||||
@elem.style.left = '0'
|
||||
@elem.style.right = '0'
|
||||
@elem.style.bottom = '0'
|
||||
@elem.style.background = "#004"
|
||||
@view.appendChild @elem
|
||||
|
||||
@renderer = new THREE.WebGLRenderer
|
||||
antialias: true
|
||||
logarithmicDepthBuffer: true
|
||||
autoClear: true
|
||||
|
||||
@renderer.setClearColor 0x008800
|
||||
@elem.appendChild @renderer.domElement
|
||||
@renderer.setSize @view.offsetWidth, @view.offsetHeight
|
||||
|
||||
|
||||
# 0000000 0000000 00 00 00000000 00000000 0000000
|
||||
# 000 000 000 000 000 000 000 000 000 000
|
||||
# 000 000000000 000000000 0000000 0000000 000000000
|
||||
# 000 000 000 000 0 000 000 000 000 000 000
|
||||
# 0000000 000 000 000 000 00000000 000 000 000 000
|
||||
|
||||
@fov = 60
|
||||
@near = 10
|
||||
@far = 1000
|
||||
@aspect = @view.offsetWidth / @view.offsetHeight
|
||||
@dist = 20
|
||||
|
||||
@camera = new THREE.PerspectiveCamera @fov, @aspect, @near, @far
|
||||
@camera.position.z = @dist
|
||||
|
||||
# 0000000 0000000 00000000 000 000 00000000
|
||||
# 000 000 000 0000 000 000
|
||||
# 0000000 000 0000000 000 0 000 0000000
|
||||
# 000 000 000 000 0000 000
|
||||
# 0000000 0000000 00000000 000 000 00000000
|
||||
|
||||
@scene = new THREE.Scene()
|
||||
@geom = new THREE.BoxGeometry 10, 10, 10
|
||||
|
||||
# 000 000 0000000 000 000 000000000
|
||||
# 000 000 000 000 000 000
|
||||
# 000 000 000 0000 000000000 000
|
||||
# 000 000 000 000 000 000 000
|
||||
# 0000000 000 0000000 000 000 000
|
||||
|
||||
@sun = new THREE.PointLight 0xffff00
|
||||
@sun.position.copy @camera.position
|
||||
@scene.add @sun
|
||||
|
||||
@ambient = new THREE.AmbientLight 0x444444
|
||||
@scene.add @ambient
|
||||
|
||||
# @material = new THREE.MeshPhongMaterial
|
||||
# color: 0xff0000
|
||||
# side: THREE.FrontSide
|
||||
# shading: THREE.SmoothShading
|
||||
# transparent: true
|
||||
# opacity: 0.85
|
||||
# shininess: 0
|
||||
#
|
||||
# @mesh = new THREE.Mesh @geom, @material
|
||||
# @scene.add @mesh
|
||||
|
||||
@animate()
|
||||
|
||||
# 0000000 000000000 00000000 00000000
|
||||
# 000 000 000 000 000
|
||||
# 0000000 000 0000000 00000000
|
||||
# 000 000 000 000
|
||||
# 0000000 000 00000000 000
|
||||
|
||||
animationStep: (step) =>
|
||||
|
||||
@quat = @camera.quaternion.clone()
|
||||
@quat.multiply (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(1,0,0), step.dsecs*0.2)
|
||||
@quat.multiply (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,1,0), step.dsecs*0.1)
|
||||
@camera.position.set(0,0,@dist).applyQuaternion @quat
|
||||
@camera.quaternion.copy @quat
|
||||
@sun.position.copy @camera.position
|
||||
@renderer.render @scene, @camera
|
||||
|
||||
reset: ->
|
||||
@elem.style.display = 'block'
|
||||
@resume()
|
||||
|
||||
stop: ->
|
||||
@elem.style.display = 'none'
|
||||
@pause()
|
||||
|
||||
resized: (w,h) ->
|
||||
@aspect = w/h
|
||||
@camera?.aspect = @aspect
|
||||
@camera.updateProjectionMatrix()
|
||||
@renderer?.setSize w,h
|
||||
|
||||
module.exports = Kiki
|
362
coffee/world.coffee
Normal file
362
coffee/world.coffee
Normal file
|
@ -0,0 +1,362 @@
|
|||
|
||||
log = require "/Users/kodi/s/ko/js/tools/log"
|
||||
KQuaternion = require './lib/quaternion'
|
||||
KVector = require './lib/vector'
|
||||
|
||||
class KikiWorld
|
||||
|
||||
constructor: ->
|
||||
|
||||
# execfile(kikipy_path + "colors.py")
|
||||
# execfile(kikipy_path + "action.py")
|
||||
# execfile(kikipy_path + "lang.py")
|
||||
# execfile (kikipy_path + "config.py")
|
||||
# execfile (kikipy_path + "setup.py")
|
||||
# execfile (kikipy_path + "levelselection.py")
|
||||
# execfile (kikipy_path + "highscore.py")
|
||||
# execfile (kikipy_path + "intro.py")
|
||||
|
||||
globals().rot0 = KQuaternion()
|
||||
globals().rotz180 = KQuaternion.rotationAroundVector(180, KVector(0,0,1))
|
||||
globals().rotz90 = KQuaternion.rotationAroundVector(90, KVector(0,0,1))
|
||||
globals().roty270 = KQuaternion.rotationAroundVector(270, KVector(0,1,0))
|
||||
globals().roty180 = KQuaternion.rotationAroundVector(180, KVector(0,1,0))
|
||||
globals().roty90 = KQuaternion.rotationAroundVector(90, KVector(0,1,0))
|
||||
globals().roty0 = KQuaternion.rotationAroundVector(0, KVector(0,1,0))
|
||||
globals().rotx180 = KQuaternion.rotationAroundVector(180, KVector(1,0,0))
|
||||
globals().rotx90 = KQuaternion.rotationAroundVector(90, KVector(1,0,0))
|
||||
|
||||
@levelList = [
|
||||
"start", "steps", "move", "electro", "elevate", "throw", # intro
|
||||
"gold", "jump", "escape", "gears", "gamma", "cube", "switch", "borg", # easy
|
||||
"mini", "blocks", "bombs", "sandbox", "energy", "maze", "love",
|
||||
"towers", "edge", "random", "plate", "nice", "entropy", # medium
|
||||
"grasp", "fallen", "cheese", "invisimaze", "spiral", # owen hay's levels (TODO: sort in)
|
||||
"slick", "bridge", "flower", "stones", "walls", "grid", # difficult
|
||||
"rings", "core", "bronze", "pool", # difficult
|
||||
"hidden", "church", "strange", "mesh", "columns", "machine", # tough
|
||||
"neutron", "captured", "circuit", "regal", "conductor", "evil", # very hard
|
||||
"mutants", # outro
|
||||
]
|
||||
|
||||
@levelDict = {}
|
||||
|
||||
# import the levels
|
||||
for levelName in @levelList
|
||||
@levelDict[levelName] = require "./levels/#{levelName}"
|
||||
|
||||
log 'levelDict', @levelDict
|
||||
@preview = false
|
||||
|
||||
# 0000000 00000000 00000000 0000000 000000000 00000000
|
||||
# 000 000 000 000 000 000 000 000
|
||||
# 000 0000000 0000000 000000000 000 0000000
|
||||
# 000 000 000 000 000 000 000 000
|
||||
# 0000000 000 000 00000000 000 000 000 00000000
|
||||
|
||||
create: (worldDict={}) -> # creates the world from a level name or a dictionary
|
||||
|
||||
log "world.create", worldDict
|
||||
|
||||
if worldDict
|
||||
if _.isString worldDict
|
||||
world.level_index = levelList.index worldDict
|
||||
world.level_name = worldDict
|
||||
@dict = levelDict[worldDict]
|
||||
else
|
||||
@dict = worldDict
|
||||
|
||||
# ............................................................ appearance
|
||||
|
||||
world.setSize @dict["size"]
|
||||
|
||||
if "scheme" in @dict
|
||||
applyColorScheme eval(@dict["scheme"])
|
||||
else
|
||||
applyColorScheme default_scheme
|
||||
|
||||
if "border" in @dict
|
||||
border = @dict["border"]
|
||||
else
|
||||
border = 1
|
||||
|
||||
world.setDisplayBorder border
|
||||
|
||||
# ............................................................ intro text
|
||||
if "intro" in @dict
|
||||
if not @preview
|
||||
intro_text = KikiScreenText()
|
||||
intro_text.addText @dict["intro"]
|
||||
intro_text.show()
|
||||
world.setName @dict["intro"]
|
||||
else
|
||||
world.setName "noname"
|
||||
|
||||
if @preview
|
||||
world.getProjection().setViewport(0.0, 0.4, 1.0, 0.6)
|
||||
else
|
||||
world.getProjection().setViewport(0.0, 0.0, 1.0, 1.0)
|
||||
|
||||
# ............................................................ escape
|
||||
escape_event = Controller.getEventWithName ("escape")
|
||||
escape_event.removeAllActions()
|
||||
escape_event.addAction(continuous(@escape, "escape"))
|
||||
|
||||
# ............................................................ exits
|
||||
|
||||
if "exits" in @dict
|
||||
exit_id = 0
|
||||
for entry in @dict["exits"]
|
||||
exit_gate = KikiGate (entry["active"])
|
||||
|
||||
if "name" in entry
|
||||
name = entry["name"]
|
||||
else
|
||||
name = "exit "+str(exit_id)
|
||||
exit_gate.setName(name)
|
||||
|
||||
exit_action = once ("exit " + str(exit_id))
|
||||
delay_action = once (lambda a = exit_action: Controller.timer_event.addAction (a))
|
||||
exit_gate.getEventWithName ("enter").addAction (delay_action)
|
||||
if "position" in entry
|
||||
pos = world.decenter (entry["position"])
|
||||
else if "coordinates" in entry
|
||||
pos = KikiPos entry["coordinates"]
|
||||
world.addObjectAtPos exit_gate, pos
|
||||
exit_id += 1
|
||||
|
||||
# ............................................................ creation
|
||||
|
||||
if "create" in @dict
|
||||
if _.isFunction @dict["create"]
|
||||
@dict["create"]()
|
||||
else
|
||||
exec @dict["create"] in globals()
|
||||
|
||||
# ............................................................ player
|
||||
|
||||
player = Controller.player
|
||||
|
||||
player_dict = @dict["player"]
|
||||
|
||||
if "orientation" in player_dict
|
||||
player.setOrientation (player_dict["orientation"])
|
||||
else
|
||||
player.setOrientation (roty90)
|
||||
|
||||
if "position" in player_dict
|
||||
world.addObjectAtPos player, world.decenter(player_dict["position"])
|
||||
else if "coordinates" in player_dict
|
||||
pos = player_dict["coordinates"]
|
||||
world.addObjectAtPos player, KikiPos(pos[0], pos[1], pos[2])
|
||||
|
||||
if "nostatus" in player_dict
|
||||
if player_dict["nostatus"] or @preview
|
||||
Controller.player_status.hide()
|
||||
else
|
||||
Controller.player_status.show()
|
||||
else
|
||||
if @preview
|
||||
Controller.player_status.hide()
|
||||
else
|
||||
Controller.player_status.show()
|
||||
|
||||
world.getProjection().setPosition (KVector())
|
||||
|
||||
Controller.player.getStatus().setMinMoves (highscore.levelParMoves (world.level_name))
|
||||
Controller.player.getStatus().setMoves (0)
|
||||
|
||||
# ............................................................ init
|
||||
world.init() # tell the world that we are finished
|
||||
|
||||
restart: (self) ->
|
||||
# restores the player status and restarts the current level
|
||||
Controller.player.getStatus().setMoves (0)
|
||||
Controller.player.reborn()
|
||||
@create()
|
||||
|
||||
finish: (self) ->
|
||||
# saves the current level status in highscore file
|
||||
highscore.levelFinished world.level_name, Controller.player.getStatus().getMoves()
|
||||
|
||||
resetPlayer: (self) ->
|
||||
# reset the player to it's original position and orientation
|
||||
|
||||
player_dict = @dict["player"]
|
||||
player = Controller.getPlayer()
|
||||
|
||||
if "reset orientation" in player_dict
|
||||
player.setOrientation player_dict["reset orientation"]
|
||||
else if "orientation" in player_dict
|
||||
player.setOrientation player_dict["orientation"]
|
||||
else
|
||||
player.setOrientation rot0
|
||||
|
||||
if "reset position" in player_dict
|
||||
world.moveObjectToPos player, world.decenter(player_dict["reset position"])
|
||||
else
|
||||
world.moveObjectToPos player, world.decenter(player_dict["position"])
|
||||
|
||||
performAction: (name, time) ->
|
||||
# action callback. used to exit current world
|
||||
if name.find ("exit") == 0
|
||||
@finish()
|
||||
Controller.player.getStatus().setMoves (0)
|
||||
if "world" in @dict["exits"][parseInt name.slice 5]
|
||||
w = @dict["exits"][parseInt name.slice 5]["world"]
|
||||
if w instanceof KikiWorld
|
||||
w.create()
|
||||
else if _.isFunction w
|
||||
w()
|
||||
else
|
||||
exec "KikiWorld().create(" + world + ")"
|
||||
else
|
||||
KikiPyWorld().create (levelList[world.level_index+1])
|
||||
|
||||
activate: (objectName) ->
|
||||
# activates object with name objectName
|
||||
object = @getObjectWithName(objectName)
|
||||
if object.getClassName() == "KikiSwitch"
|
||||
kikiObjectToSwitch(object).setActive(1)
|
||||
else if object.getClassName() == "KikiGate"
|
||||
kikiObjectToGate(object).setActive(1)
|
||||
|
||||
decenter: () ->
|
||||
s = @getSize()
|
||||
if len(args) == 3
|
||||
[x, y, z] = args
|
||||
else if len(args) == 1
|
||||
[x, y, z] = args[0]
|
||||
|
||||
return KikiPos(x+s.x/2, y+s.y/2, z+s.z/2)
|
||||
|
||||
addObjectLine: (object, start, end) ->
|
||||
# adds a line of objects of type to the world. start and end should be 3-tuples or KikiPos objects
|
||||
if start instanceof KikiPos
|
||||
start = [start.x, start.y, start.z]
|
||||
[sx, sy, sz] = start
|
||||
if end isinstance KikiPos
|
||||
end = [end.x, end.y, end.z]
|
||||
[ex, ey, ez] = end
|
||||
|
||||
diff = [ex-sx, ey-sy, ez-sz]
|
||||
maxdiff = _.max diff.map Math.abs
|
||||
deltas = diff.map (a) -> a/maxdiff
|
||||
for i in [0...maxdiff]
|
||||
# pos = apply(KikiPos, (map (lambda a, b: int(a+i*b), start, deltas)))
|
||||
pos = KikiPos (start[j]+i*deltas[j] for j in [0..2])
|
||||
if @isUnoccupiedPos pos
|
||||
if type(object) == types.StringType
|
||||
@addObjectAtPos eval(object), pos
|
||||
else
|
||||
@addObjectAtPos object(), pos
|
||||
|
||||
addObjectPoly: (object, points, close=1) ->
|
||||
# adds a polygon of objects of type to the world. points should be 3-tuples or KikiPos objects
|
||||
if close
|
||||
points.append (points[0])
|
||||
for index in range(1, len(points))
|
||||
@addObjectLine object, points[index-1], points[index]
|
||||
|
||||
addObjectRandom: (object, number) ->
|
||||
# adds number objects of type at random positions to the world
|
||||
for i in [0...number]
|
||||
if type (object) == types.StringType
|
||||
@setObjectRandom (eval(object))
|
||||
else
|
||||
@setObjectRandom (object())
|
||||
|
||||
setObjectRandom: (object) ->
|
||||
# adds number objects of type at random positions to the world
|
||||
size = @getSize()
|
||||
object_set = 0
|
||||
while not object_set # hack alert!
|
||||
random_pos = KikiPos random.randrange(size.x),
|
||||
random.randrange(size.y),
|
||||
random.randrange(size.z)
|
||||
if not object.isSpaceEgoistic() or @isUnoccupiedPos(random_pos)
|
||||
@addObjectAtPos object, random_pos
|
||||
object_set = 1
|
||||
|
||||
help: (index=0) ->
|
||||
# displays help messages
|
||||
|
||||
# text_list = @dict["help"]
|
||||
# more_text = index < len (text_list) - 1
|
||||
# less_text = index > 0
|
||||
#
|
||||
# list = text_list[index].split("$key(")
|
||||
# for i in range (1, len(list))
|
||||
# close = list[i].find(")")
|
||||
# list[i] = Controller.player.getKeyForAction (list[i][:close]) + list[i][close+1:]
|
||||
#
|
||||
# list.append ("\n\n$scale(0.5)(%d/%d)" % (index+1, len (text_list)))
|
||||
# help_text = KikiPageText ("".join(list), more_text, less_text)
|
||||
#
|
||||
# if more_text:
|
||||
# help_text.getEventWithName ("next").addAction (once (lambda i=index+1: @help (i)))
|
||||
# if less_text:
|
||||
# help_text.getEventWithName ("previous").addAction (once (lambda i=index-1: @help (i)))
|
||||
|
||||
outro: (index=0) ->
|
||||
# well hidden outro :-)
|
||||
outro_text = """
|
||||
$scale(1.5)congratulations!\n\n$scale(1)you rescued\nthe nano world!
|
||||
|
||||
the last dumb mutant bot\nhas been destroyed.\n\nthe maker is functioning again.
|
||||
kiki will go now\nand see all his new friends.\n\nyou should maybe\ndo the same?
|
||||
the maker wants to thank you!\n\n(btw.: you thought\nyou didn't see\nkiki's maker in the game?
|
||||
you are wrong!\nyou saw him\nall the time,\nbecause kiki\nlives inside him!)\n\n$scale(1.5)the end
|
||||
p.s.: the maker of the game\nwants to thank you as well!\n\ni definitely want your feedback:
|
||||
please send me a mail (monsterkodi@users.sf.net)\nwith your experiences,
|
||||
which levels you liked, etc.\n\nthanks in advance and have a nice day,\n\nyours kodi
|
||||
"""
|
||||
|
||||
more_text = index < outro_text.length-1
|
||||
less_text = index > 0
|
||||
|
||||
page_text = outro_text[index]
|
||||
page_text += "\n\n$scale(0.5)(#{index+1}/#{outro_text.length})"
|
||||
|
||||
page = KikiPageText(page_text, more_text, less_text)
|
||||
page.getEventWithName("hide").addAction(once(display_main_menu))
|
||||
|
||||
if more_text
|
||||
page.getEventWithName("next").addAction (i=index+1) => @outro i
|
||||
if less_text
|
||||
page.getEventWithName("previous").addAction (i=index-1) => @outro i
|
||||
|
||||
resetProjection: -> world.getProjection().setViewport 0.0, 0.0, 1.0, 1.0
|
||||
|
||||
toggle: (objectName) ->
|
||||
# toggles object with name objectName
|
||||
Controller.startTimedAction(@getObjectWithName(objectName).getActionWithName("toggle"))
|
||||
|
||||
escape: (self) -> # handles an ESC key event
|
||||
|
||||
@resetProjection()
|
||||
|
||||
if "escape" in @dict
|
||||
if _.isFunction @dict["escape"]
|
||||
@dict["escape"]()
|
||||
else
|
||||
exec @dict["escape"] in globals()
|
||||
return
|
||||
|
||||
menu = KikiMenu()
|
||||
menu.getEventWithName ("hide").addAction (once(@resetProjection))
|
||||
|
||||
# if Controller.isDebugVersion()
|
||||
# menu.addItem (Controller.getLocalizedString("next level"), once(lambda w=self: w.performAction("exit 0",0)))
|
||||
# if "help" in @dict
|
||||
# menu.addItem (Controller.getLocalizedString("help"), once(@help))
|
||||
menu.addItem(Controller.getLocalizedString("restart"), once(@restart))
|
||||
|
||||
esc_menu_action = once (@escape)
|
||||
console.out("level_index %d" % world.level_index)
|
||||
menu.addItem(Controller.getLocalizedString("load level"), (i=world.level_index,a=esc_menu_action) -> levelSelection(i, a))
|
||||
menu.addItem(Controller.getLocalizedString("setup"), once(quickSetup))
|
||||
menu.addItem(Controller.getLocalizedString("about"), once(display_about))
|
||||
menu.addItem(Controller.getLocalizedString("quit"), once(Controller.quit))
|
||||
|
||||
module.exports = KikiWorld
|
Loading…
Reference in New Issue
Block a user