Hammer Jump Prototype

Sup guys! This is a prototype for a platformer game I’m working on. Try it out and leave a comment with what you’d like to see in the game! Thanks in advance!!!


--# Main
-- Hammer Jump

supportedOrientations(LANDSCAPE_ANY)
displayMode(FULLSCREEN)
-- Use this function to perform your initial setup
function setup()
    player = Player()
    block = Block()

    makeTutorial()
end

-- This function gets called once every frame
function draw()
    background(40, 40, 50)
    strokeWidth(5)
    
    if fade > 0 then
        tint(255, 255, 255, fade)
        sprite(tutorial,WIDTH/2,HEIGHT/2)
        fade = fade - 0.5
    end
    
    player:draw()
    block:draw()
    
    -- line(0,150,WIDTH,150)
    -- line(0,450,WIDTH,450)
    line(0,100,WIDTH,100)
    line(0,300,WIDTH,300)
    line(0,500,WIDTH,500)
end

function touched(touch)
    player:touched(touch)
end

function makeTutorial()
    tutorial = image(WIDTH,HEIGHT)
    setContext(tutorial)
    strokeWidth(10)
    noFill()
    stroke(255, 255, 255, 118)
    ellipse(WIDTH-100,550,70)
    ellipse(WIDTH-100,350,70)
    ellipse(WIDTH-100,150,70)
    ellipse(150,200,140)
    textMode(CENTER)
    font("Futura-Medium")
    fontSize(20)
    fill(255, 255, 255, 118)
    text("AVOID THE FALLING BLOCK",300,650)
    text("TAP HERE",150,215)
    text("TO ATTACK",150,185)
    text("TAP HERE",WIDTH-100,600)
    text("HERE",WIDTH-100,400)
    text("AND HERE",WIDTH-100,200)
    text("TO JUMP",WIDTH-100,70)
    text("BETWEEN LEVELS",WIDTH-100,45)
    setContext()
    fade = 255
end
    


--# Player
Player = class()

function Player:init()
    self.x = WIDTH/2
    self.y = 350
    self.direction = 1
    self.speed = 5
    self.state = "middle"
    self.angle = 45
    for i,v in pairs(self) do print(i.." = "..v) end
    self.attack = false
end

function Player:draw()
    pushMatrix()
    translate(self.x+math.sin(ElapsedTime*10)*3,self.y+math.sin(ElapsedTime*10)*3)
    noFill()
    stroke(255, 255, 255, 255)
    ellipse(0,0,100,100)
    scale(-self.direction,1)
    translate(-20,-10)
    rotate(self.angle-math.sin(ElapsedTime*10)*3)
    line(0,0,0,65)
    translate(0,90)
    rect(-50,-25,100,50)
    popMatrix()
    if self.x < 50 then self.direction = 1 end
    if self.x > WIDTH-50 then self.direction = -1 end
    -- self.speed = self.speed * 1.0001
    self.x = self.x + self.speed * self.direction
end

function Player:touched(touch)
    if touch.state == BEGAN and touch.x >= WIDTH/2
    and self.state ~= "jumping" --[[and self.attack == false]] then
        if touch.y <= 200 and self.state ~= "bottom" then
            self:jumpDown(150,"bottom")
        elseif touch.y <= 400 and touch.y > 200 and self.state ~= "middle" then
            if self.state == "top" then self:jumpDown(350,"middle")
            else self:jumpUp(350,"middle") end
        elseif touch.y > 400 and self.state ~= "top" then
            self:jumpUp(550,"top")
        end
    end
    
    if touch.state == BEGAN and touch.x < WIDTH/2
    --[[and self.state ~= "jumping"]] and self.attack == false then
        self:hammer()
    end
end

function Player:jumpUp(height,level)
    self.state = "jumping"
    tween(0.3,self,{y = height}, tween.easing.backOut,function() self.state = level end)
end

function Player:jumpDown(height,level)
    self.state = "jumping"
    tween(0.3,self,{y = height},tween.easing.backIn,function() self.state = level end)
end

function Player:hammer()
    self.attack = true
    local t1 = tween(0.1,self,{angle = -45})
    local t2 = tween(0.05,self,{angle = 90})
    local t3 = tween(0.1,self,{angle = 45})
    local t4 = tween.delay(0.01,function() self.attack = false end)
    tween.sequence(t1,t2,t3,t4)
end


--# Block
Block = class()

function Block:init()
    -- you can accept and set parameters here
    self.x = math.random(50,WIDTH-50)
    self.y = HEIGHT + 50
    local t1 = tween(0.7,self,{y = 550},tween.easing.quartIn)
    local t2 = tween(0.7,self,{y = 350},tween.easing.quartIn)
    local t3 = tween(0.7,self,{y = 150},tween.easing.quartIn)
    local t4 = tween(0.7,self,{y = -50},tween.easing.quartIn)
    tween.sequence(t1,t2,t3,t4)
end

function Block:draw()
    -- Codea does not automatically call this method
    pushMatrix()
    translate(self.x,self.y)
    rect(-60,-50,120,100)
    popMatrix()
    if self.y == -50 then self:init() end
end

function Block:touched(touch)
    -- Codea does not automatically call this method
end

A couple of suggestions to improve performance. These probably won’t make a difference in such a small program, but as your programs get larger, it’s worth optimising like this.

You calculate math.sin(ElapsedTime)*3 three separate times in Player:draw, better is to calculate just once and store in a local variable.

Instead of drawing the player from scratch every time, start by drawing it into an image using setContext, then just sprite the image after that.

Also, there are lots of hard coded numbers scattered through the program. If you ever decide to change the size of your scene, or you need to adjust it for different resolution screens, it could be a lot of work. In the touched function, for example, I suggest replacing the numbers with a fraction of Width and Height, eg Width/3, so it works on any size screen. I also prefer to set a standard scale, eg s=10, and my players and objects are all sized based on that. I can make them bigger or smaller just by changing the value of s.

Thanks @Ignatz, really great suggestions! I was already planning to fix some of those when I finalized the game a bit more, but it’s always great to be reminded!

super cool, i look forward to the optimised version