Computer Science Canada

Basic platformer

Author:  iker [ Mon May 01, 2006 7:41 pm ]
Post subject:  Basic platformer

Here's a little platforming action I put together, all turing graphics, and great collision detection.

Keys:
LEFT & RIGHT arrows - move left and right
SPACE - jump
CTRL - crouch

Functions:
Walking - left, right, jump, crouch
Hanging - left, right, jump up (jump), fall (crouch)

There's nothing but simple platform movement, no baddies, no weapons, no health, just movement.

code:

setscreen ("graphics,offscreenonly")
var x, y, ang, bodyLength, maxYSpeed : int := 15
var ySpeed : real := 0
ySpeed := 0
var key : array char of boolean
var inAir, yGood, left, hang : boolean := false

proc walkLeft
    if key (KEY_LEFT_ARROW) then
        ang -= 7
        x -= 3
        left := true
        for i : 1 .. 15
            if View.WhatDotColor (x, y + i) = black then
                y += 1
            end if
        end for
    end if
end walkLeft

proc walkRight
    if key (KEY_RIGHT_ARROW) then
        ang += 7
        x += 3
        for i : 1 .. 15
            if View.WhatDotColor (x, y + i) = black then
                y += 1
            end if
        end for
        left := false
    end if
end walkRight

proc jump
    if hang = false then
        if bodyLength = 33 and key (' ') and inAir = false then
            y -= 2
        elsif key (' ') and inAir = false then
            ySpeed := 10
        end if
    else
        if key (' ') and inAir = false then
            ySpeed := 13
        end if
    end if
end jump

proc crouch
    if key (KEY_CTRL) then
        bodyLength := 33
    else
        bodyLength := 45
    end if
end crouch

proc gravityAndCheck
    if View.WhatDotColor (x, y) ~= black and hang = false then
        inAir := true
    end if
    hang := false
    yGood := false
    if ySpeed > 0 then
        y += round (ySpeed)
    elsif ySpeed < 0 then
        for decreasing i : 0 .. round (ySpeed)
            if View.WhatDotColor (x, y + i) ~= black and yGood = false then
                if View.WhatDotColor (x, y + bodyLength + i + 15) = black then
                    yGood := true
                    inAir := false
                    ySpeed := 0
                    hang := true
                else
                    hang := false
                end if
                if hang = false then
                    y -= 1
                end if
            else
                yGood := true
                inAir := false
                ySpeed := 0
            end if
        end for
    end if
    if View.WhatDotColor (x, y) ~= black then
        ySpeed -= 1.25
    end if
end gravityAndCheck

proc drawScreen
    Draw.ThickLine (0, 5, maxx, 5, 2, black)
    %platforms
    for yi : 50 .. 250 by 50
        Draw.ThickLine (yi, yi, yi + 60, yi, 2, black)
    end for
    Draw.ThickLine (300, 300, maxx, 300, 2, black)
end drawScreen

proc drawGuy
    drawline (x, y + 20, x, y + bodyLength, black)
    %legs
    drawline (x, y + 20, x + round (sind (ang) * 5), y + 20 + round (cosd (ang) * 10), black)
    drawline (x, y + 20, x + round (sind (ang + 180) * 5), y + 20 + round (cosd (ang + 180) * 10), black)
    drawline (x + round (sind (ang) * 5), y + 20 + round (cosd (ang) * 10), x + round (sind (ang) * 5), y + 5 + round (cosd (ang) * 10), black)
    drawline (x + round (sind (ang + 180) * 5), y + 20 + round (cosd (ang + 180) * 10), x + round (sind (ang + 180) * 5), y + 5 + round (cosd (ang + 180) * 10), black)
    %arms
    ang += 90
    drawline (x, y + bodyLength - 2, x + round (sind (ang) * 5), y + bodyLength - 2 + round (cosd (ang) * 10), black)
    drawline (x, y + bodyLength - 2, x + round (sind (ang + 180) * 5), y + bodyLength - 2 + round (cosd (ang + 180) * 10), black)
    if hang = false then
        if left = true then
            drawline (x + round (sind (ang) * 5), y + bodyLength - 2 + round (cosd (ang) * 10), x + round (sind (ang) * 5) - 7, y + bodyLength - 10 + round (cosd (ang) * 10), black)
            drawline (x + round (sind (ang + 180) * 5), y + bodyLength - 2 + round (cosd (ang + 180) * 10), x + round (sind (ang + 180) * 5) - 7, y + bodyLength - 10 + round (cosd (ang + 180) * 10),
                black)
        else
            drawline (x + round (sind (ang) * 5), y + bodyLength - 2 + round (cosd (ang) * 10), x + round (sind (ang) * 5) + 7, y + bodyLength - 10 + round (cosd (ang) * 10), black)
            drawline (x + round (sind (ang + 180) * 5), y + bodyLength - 2 + round (cosd (ang + 180) * 10), x + round (sind (ang + 180) * 5) + 7, y + bodyLength - 10 + round (cosd (ang + 180) * 10),
                black)
        end if
        ang -= 90
    else
        if left = true then
            drawline (x + round (sind (ang) * 5), y + bodyLength - 2 + round (cosd (ang) * 10), x + round (sind (ang) * 5), y + bodyLength + 10 + round (cosd (ang) * 10), black)
            drawline (x + round (sind (ang + 180) * 5), y + bodyLength - 2 + round (cosd (ang + 180) * 10), x + round (sind (ang + 180) * 5), y + bodyLength + 10 + round (cosd (ang + 180) * 10),
                black)
        else
            drawline (x + round (sind (ang) * 5), y + bodyLength - 2 + round (cosd (ang) * 10), x + round (sind (ang) * 5), y + bodyLength + 10 + round (cosd (ang) * 10), black)
            drawline (x + round (sind (ang + 180) * 5), y + bodyLength - 2 + round (cosd (ang + 180) * 10), x + round (sind (ang + 180) * 5), y + bodyLength + 10 + round (cosd (ang + 180) * 10),
                black)
        end if
        ang -= 90
    end if
    %head
    drawoval (x, y + bodyLength + 5, 5, 5, black)
    drawfilloval (x, y + bodyLength + 5, 4, 4, white)
end drawGuy

loop
    Input.KeyDown (key)
    drawScreen
    jump
    crouch
    gravityAndCheck
    walkLeft
    walkRight
    drawGuy
    ang := ang mod 360
    View.Update
    delay (10)
    cls
    if x < 0 or x > maxx or y < 0 or y > maxy then
        x := 5
        y := 5
    end if
end loop

Author:  Cervantes [ Mon May 01, 2006 8:04 pm ]
Post subject: 

Crouch & Jump seems to push me back to the start (bottom left corner). If I'm on a platform at that time, I seem to fall through the platform, first.

Pretty cool graphics!

Author:  codemage [ Tue May 02, 2006 8:03 am ]
Post subject: 

Unless that's on purpose to let you jump down from a platform (just as CTRL lets you drop down when you're hanging).

I like the hanging bit. The whole thing is very "stickman sam" without the shooting.

Author:  BenLi [ Tue May 02, 2006 3:31 pm ]
Post subject: 

I like it, just more levels, and you'll be in bussiness

Author:  MattyGG [ Tue May 02, 2006 5:48 pm ]
Post subject: 

problem...when i jump while trying to go off-screen to the left, it disables the jump for the rest of the time using the program

Author:  iker [ Tue May 02, 2006 7:43 pm ]
Post subject: 

Fixed it up a bit, added some better graphics, made it more of a "game". 3 levels, and you can make levels easily. In a future version that I'm making, I'm adding in a level timer, to actualy make it a game. Don't fall too much or you'll die (just restart that level).

After you finish the last level it just crashes unless you have another level made... so make some levels and post them here so the game can continue forever... and ever... and when I actualy make the game, I'll add in some of your best levels.

Anyways, have some fun with making some challenging levels. I will have a level maker in the next post, to make it alot easier. Remember that you can climb across, and yes, crouching and jumping is supposed to make you fall through.

one last thing, try to make it out the far left exit in the first level, if you can figure out how (and yes, there is a way)

Author:  iker [ Tue May 02, 2006 8:48 pm ]
Post subject: 

mapmaker, works with anything if modded (go for it)
make sure you save it to the same directory as the game

[1]click a tile on the bottom to select
[2]click a position on the board to place tile
[3]rinse and repeat if necessary

click S and then type a number then press ENTER to save
click L and then type a number then press ENTER to load
will save as level#.txt and will load level#.txt (unless modded)

elegable maps must include
[1]a single outline of "metal" (won't be editable anyways unless program modded)
[2]atleast 1 exit, may include more "challenging but faster" exits
[3]ground peice at bottom left corner (spawn point)
for them to be placed in future versions of the game

code:

setscreen ("graphics:550;450,offscreenonly,nobuttonbar")
var font1 : int := Font.New ("serif:25")
var mx, my, mb, Level, fileNo, info, current, count : int := 0
var tiles : array 0 .. 9 of int
var xy : array 0 .. 19, 0 .. 15 of int
for i : 0 .. 9
    tiles (i) := Pic.FileNew ("images/fore0" + intstr (i) + ".bmp")
end for
for x : 0 .. 19
    for y : 0 .. 14
        xy (x, y) := 1
    end for
end for

proc exportLevel
    get Level
    count := 1
    open : fileNo, "levels/level" + intstr (Level) + ".txt", put
    for decreasing y : 14 .. 0
        for x : 0 .. 19
            info := xy (x, y)
            put : fileNo, info
        end for
    end for
    close : fileNo
end exportLevel

proc importLevel
    get Level
    open : fileNo, "levels/level" + intstr (Level) + ".txt", get
    for decreasing y : 14 .. 0
        for x : 0 .. 19
            get : fileNo, info
            xy (x, y) := info
        end for
    end for
    close : fileNo
end importLevel

proc drawScreen
    Font.Draw ("L", 0 + 2, 17 * 25, font1, red)
    Font.Draw ("S", 25 + 3, 17 * 25, font1, red)
    drawbox (0, 17 * 25, 25, 18 * 25, black)
    drawbox (25, 17 * 25, 50, 18 * 25, black)
    Pic.Draw (tiles (current), 0, 0, picMerge)
    drawbox (0, 0, 25, 25, black)
    for i : 0 .. 9
        Pic.Draw (tiles (i), i * 25 + 50, 0, picMerge)
        drawbox (i * 25 + 50, 0, i * 25 + 25 + 50, 25, black)
    end for
    for x : 0 .. 19
        for y : 0 .. 14
            Pic.Draw (tiles (xy (x, y)), x * 25 + 25, y * 25 + 50, picMerge)
        end for
    end for
end drawScreen

proc setTile
    if my = 0 and mb = 1 then
        if mx = 2 then
            current := 0
        elsif mx = 3 then
            current := 1
        elsif mx = 4 then
            current := 2
        elsif mx = 5 then
            current := 3
        elsif mx = 6 then
            current := 4
        elsif mx = 7 then
            current := 5
        elsif mx = 8 then
            current := 6
        elsif mx = 9 then
            current := 7
        elsif mx = 10 then
            current := 8
        elsif mx = 11 then
            current := 9
        end if
    end if
end setTile

proc setXYOnMap
    mx := mx - 1
    my := my - 2
    if mb = 1 and mx >= 1 and my >= 1 and mx <= 18 and my <= 13 then
        xy (mx, my) := current
    end if
    mx := mx + 1
    my := my + 2
end setXYOnMap

proc loadSave
    if mb = 1 and my = 17 then
        if mx = 0 then
            importLevel
        elsif mx = 1 then
            exportLevel
        end if
    end if
end loadSave

loop
    Mouse.Where (mx, my, mb)
    mx := mx div 25
    my := my div 25
    drawScreen
    setTile
    setXYOnMap
    loadSave
    mx := mx * 25 + 12
    my := my * 25 + 12
    drawfilloval (mx, my, 3, 3, brightred)
    View.Update
    Time.DelaySinceLast (10)
    cls
end loop

Author:  NikG [ Tue May 02, 2006 11:37 pm ]
Post subject: 

Wow! Great game.

I'd love to see this with some enemies, and a scoring system (via collectible gems and the like).

+20 bits

Author:  iker [ Wed May 03, 2006 5:51 pm ]
Post subject: 

Newest update

-working steel boxes (now prevent verticle movement too)
-2 newer levels (and a few tweeks to old)
-looping game (doesn't quit after last level, starts back at 1)

future updates

-game timer
-points system (maby collectables)

I don't realy want to add enemies, but I'm thinking about the collectables. The games supposed to be just a platformer, so there a small chance for enemies.

Author:  ohgeez_ [ Fri May 05, 2006 9:55 pm ]
Post subject: 

just a question, is the game supposed to lag a little or is it just my computer's problem. the guy seems to be moving very slowly compared to the first one with just the platforms.

oh and btw. great game

Author:  NikG [ Sat May 06, 2006 1:36 am ]
Post subject: 

Doesn't lag for me ohgeez_.

btw, how do you beat level 4??
I had to cheat just to see level 5, which was easy like the first 3.

Author:  iker [ Sat May 06, 2006 3:13 pm ]
Post subject: 

There's a technique that you have to figure out on your own that allows for most of the levels to be completed very easily, and in level 4, I guess I didn't compensate for those who haven't learned the technique. And no, the technique isn't in the game like a hidden move, you just have to press the right button at the right time.has something to do with jumping and crouching
Well, here's a level pack download with level 1-8, all edited a bit to make it completable without the technique.

Author:  Carey [ Mon May 08, 2006 12:15 pm ]
Post subject:  nice........

very cool game

i found some probles though...

i just downloaded your new level pack and it wont go past level 5. maybe its because your checking for the next level procedure
code:

procedure nextLevel
    if View.WhatDotColor (x, y + 10) = brightred then
        level += 1
        levelImport
    end if
end nextLevel

and maybe you forgot to put the brightred colour in the level

also is the game supposed to go back to level 1 when you finish?
code:

proc levelImport
    realX := 37.5
    realY := 55
    ySpeed := 0
    xSpeed := 0
    life := 100
    bodyLength := 45
    colorback (white)
    cls
    loop
        if File.Exists ("levels/level" + intstr (level) + ".txt") then
            open : fileNo, "levels/level" + intstr (level) + ".txt", get
            for decreasing y : 14 .. 0
                for x : 0 .. 19
                    get : fileNo, info
                    tileImage (x, y) := info
                end for
            end for
            exit
        else
            level := 1 %||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||right here
        end if
    end loop
    locatexy (230, 190)
    put "LEVEL " + intstr (level) ..
    View.Update
    delay (1000)
end levelImport

because it just repeats level 5 over and over again

anyway some suggestions:
(1) have a lives counter and when you run out go back to level 1
(2) items that give you points, lives. etc
(3) some baddies that you have to dodge
(4) a highscore list

Author:  iker [ Mon May 08, 2006 5:56 pm ]
Post subject: 

Now, those two problems that your talking about actualy don't exist. You just fell for the Level 5 trick, ever try actualy going through the level and not trying to run across the gap? Your just falling into the pit and not completing the level. Good try though.

The baddies may or may not be added in, and a points system is being put in place, along with the "highscore list".
Now about adding in items, I'm thinking of making it so you can fly through the level, or go the long way and collect items for points. The health system is staying as is, because with the new points system, it works out.

Author:  Carey [ Tue May 09, 2006 9:29 am ]
Post subject: 

heh heh.. oops sorry that does work

Author:  Remm [ Wed May 10, 2006 7:29 pm ]
Post subject: 

Yeah... as much as i'd love to try out some of the newer versions, all the versions from the first zip file and onward dont work Confused
anyone know why? - not even the map maker will work.
i get error on line 46 in map maker
illigal picture ID number '0'.
and in the acual game, all i get is a blank screen when it loads up.
Help? i'd love to try it.

Author:  iker [ Wed May 10, 2006 8:43 pm ]
Post subject: 

I guess i might aswell zip my latest incomplete version. Newest features is the level timer, a faster process time, and a thicker character.

I sped up the program by taking a screen of both the bottom and top layers after they're loaded in the levelImport process, and then just draw the one bigger image instead to make it that much faster.
Made a timer that is always on time (depending on your computers time), because i used Time.Sec

anyways, still the same game, just with a timer Smile

Author:  Anonymous [ Thu May 11, 2006 8:47 pm ]
Post subject: 

How do you pass level 5? Of course you cant pass the pit, but I dont see another way.

Author:  NikG [ Thu May 11, 2006 9:59 pm ]
Post subject: 

where are you having problems in level 5?
my guess is at the very end so here's a hint... you gotta find a way to hang off a ledge while you're standing on it.

Author:  TheOneTrueGod [ Fri May 12, 2006 6:55 am ]
Post subject: 

Excellent program man, love how the character graphics were done in turing Wink Theres a couple bugs with it, but nothing that causes it to crash, so you've done very well.

-- I found that a couple of times, when jumping and croutching, my head would get lodged in the ceiling. Its a kind of uncomfortable pose, and my character would kinda sit there twitching for a while. He fell out eventually, but it was kinda saddening to see him in misery there for a while Razz

-- There are some other, very minor bugs with running into walls and such. Eg: If the wall of the level is beside a ledge, and you are holding onto that ledge and you try and run into the side of the level, you will start to pass into/out of the wall really quickly, and you will slowly slide down the ledge. I didn't keep trying, because I didn't want to fall off, so I don't know what would happen Razz

Anyways, keep up the awesome work, you should have something like a level building contest, give out bits as prizes Wink I'll donate some as a prize if you do.

+Bits for you


: