Author Topic: Engine for creating a Top Down view, Free Scrolling game - Source code included  (Read 1226 times)

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
EDIT: a new version has been added further down for download as a zip file which has better graphics. The engine itself is the same, just looks better.


Hi all,

The below code is an example of how to make a map style, top view, free scrolling game (think Legend of Zelda on Super Nintendo).  The graphics are simple but could easily be improved to suit your own purpose.

The main feature of this code is that the Player is not always in the centre of the screen.  As you move closer to the edge, the screen stops scrolling and the player moves freely to the edge.

Simple to use, just copy the code below and paste it into QB64 and save as ViewPortal.bas (if you want to), then run the program  ;D



Code: [Select]

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' View Portal.bas '
'''''''''''''''''''
'
' Written by Justin Richards (2012)
'
'
' Remember the old Super Nintendo and MegaDrive games that had a Top Down type
' view of the map and you would scroll around in all directions as you walked
' along?  This program does just that!  The focus is not on graphics, just the
' engine itself, although more complex graphics can easily be added at a later
' stage.
'
' Basically the program spawns the player into the level and repositions him
' based on his position within the map.  When you move close to the edge of
' the playable area (called the view portal) you detach from the centre of the
' screen and move freely until you reach the edge.  This lets the player know
' that they have reached the edge and there is nothing else further in that
' direction.
'
' The source code is free for anyone to use.  Try playing around with the
' ManX and ManY variables and see what happens.  You could also try increasing
' the View Portal and adding more tiles.
'
' Enjoy...



SCREEN _NEWIMAGE(320, 200, 256)

DIM SHARED ViewX1, ViewY1, ViewX2, ViewY2

DIM SHARED TileX1(10)
DIM SHARED TileY1(10)
DIM SHARED TileX2(10)
DIM SHARED TileY2(10)

DIM SHARED ManX, ManY


' Set Screen Limits (this example is an area 400 pixels x 400 pixels)

ViewX1Limit = 0: ViewY1Limit = 0: ViewX2Limit = 400: ViewY2Limit = 400


' Set starting co-ordinates for our Man (in this case he is just a green ball)

ManX = 120: ManY = 120


' Set the Veiw Portal to centre on the Man's co-ordinates to start with

ViewX1 = ManX - 160: ViewY1 = ManY - 100: ViewX2 = ManX + 159: ViewY2 = ManY + 99


' Test to see whether the man is close to the edge of the portal area and
' adjust the view portal position if necessary...

' X co-ordinates

IF ViewX1 < ViewX1Limit THEN

  ViewX1 = ViewX1Limit

  ViewX2 = ViewX1 + 319

ELSEIF ViewX2 < ViewX2Limit - 1 THEN

  ViewX1 = ViewX1Limit + 160 - ManX
  ViewX2 = ViewX1 + 319

ELSEIF ViewX2 > ViewX2Limit - 1 THEN

  ViewX1 = ViewX2Limit - 320

  ViewX1 = -ViewX1

  ViewX2 = ViewX1 + 319

END IF


' Y co-ordinates

IF ViewY1 < ViewY1Limit THEN

  ViewY1 = ViewY1Limit

  ViewY2 = ViewY1 + 199

ELSEIF ViewY2 < ViewY2Limit - 1 THEN

  ViewY1 = ViewY1Limit + 100 - ManY
  ViewY2 = ViewY1 + 199

ELSEIF ViewY2 > ViewY2Limit - 1 THEN

  ViewY1 = ViewY2Limit - 200

  ViewY1 = -ViewY1

  ViewY2 = ViewY1 + 199

END IF


' If the man is not near the edge than change his co-ordinates based on the
' new screen position...

IF ManX > ViewX1Limit + 160 AND ManX < ViewX2Limit - 160 THEN ManX = -ViewX1 + 160
IF ManY > ViewY1Limit + 100 AND ManY < ViewY2Limit - 100 THEN ManY = -ViewY1 + 100


' These tiles form the brown rectangles (walls) in the background

TileX1(0) = 0: TileY1(0) = 0: TileX2(0) = 39: TileY2(0) = 399
TileX1(1) = 40: TileY1(1) = 0: TileX2(1) = 359: TileY2(1) = 39
TileX1(2) = 360: TileY1(2) = 0: TileX2(2) = 399: TileY2(2) = 399
TileX1(3) = 40: TileY1(3) = 360: TileX2(3) = 359: TileY2(3) = 399
TileX1(4) = 160: TileY1(4) = 160: TileX2(4) = 239: TileY2(4) = 199
TileX1(5) = 220: TileY1(5) = 40: TileX2(5) = 239: TileY2(5) = 159
TileX1(6) = 40: TileY1(6) = 270: TileX2(6) = 199: TileY2(6) = 299


' Set Keyboard Constants

CONST Key_Up& = 18432
CONST Key_Down& = 20480
CONST Key_Left& = 19200
CONST Key_Right& = 19712


' Set delay/speed variables

TimeSet = 1

GameSpeed = 0



' Main Game Loop

DO


  ' Reset the Tick Clock

  DEF SEG = 0

  POKE 1132, 0


  ' Only process the loop if the desired delay has passed

  IF GameSpeed = TimeSet THEN


    ' Exit code

    FOR KbdLoop = 0 TO 32

      Kbd$ = ""

      Kbd$ = INKEY$

      IF Kbd$ = CHR$(27) THEN

        CLS

        _DISPLAY

        SLEEP 1

        _FULLSCREEN _OFF

        SYSTEM

      END IF

    NEXT KbdLoop


    ' Draw the Background

    DrawImages



    ' Test for collisions

    PManUpTopLeft = POINT(ManX - 20 + ViewX1, ManY - 21 + ViewY1)
    PManUpTopMiddle = POINT(ManX + ViewX1, ManY - 21 + ViewY1)
    PManUpTopRight = POINT(ManX + 19 + ViewX1, ManY - 21 + ViewY1)

    PManDownBottomLeft = POINT(ManX - 20 + ViewX1, ManY + 20 + ViewY1)
    PManDownBottomMiddle = POINT(ManX + ViewX1, ManY + 20 + ViewY1)
    PManDownBottomRight = POINT(ManX + 19 + ViewX1, ManY + 20 + ViewY1)

    PManLeftTopLeft = POINT(ManX - 21 + ViewX1, ManY - 20 + ViewY1)
    PManLeftMiddleLeft = POINT(ManX - 21 + ViewX1, ManY + ViewY1)
    PManLeftBottomLeft = POINT(ManX - 21 + ViewX1, ManY + 19 + ViewY1)

    PManRightTopRight = POINT(ManX + 20 + ViewX1, ManY - 20 + ViewY1)
    PManRightMiddleRight = POINT(ManX + 20 + ViewX1, ManY + ViewY1)
    PManRightBottomRight = POINT(ManX + 20 + ViewX1, ManY + 19 + ViewY1)


    ' Test for keypresses

    UpOn = _KEYDOWN(Key_Up&)
    DownOn = _KEYDOWN(Key_Down&)
    LeftOn = _KEYDOWN(Key_Left&)
    RightOn = _KEYDOWN(Key_Right&)


    ' Move man based on user input

    IF UpOn = -1 AND DownOn = 0 AND PManUpTopLeft = 0 AND PManUpTopMiddle = 0 AND PManUpTopRight = 0 THEN

      IF ManY > ViewY1Limit + 100 AND ManY < ViewY2Limit - 98 THEN ViewY1 = ViewY1 + 2: ViewY2 = ViewY2 + 2

      ManY = ManY - 2

    END IF

    IF DownOn = -1 AND UpOn = 0 AND PManDownBottomLeft = 0 AND PManDownBottomMiddle = 0 AND PManDownBottomRight = 0 THEN

      IF ManY > ViewY1Limit + 98 AND ManY < ViewY2Limit - 100 THEN ViewY1 = ViewY1 - 2: ViewY2 = ViewY2 - 2

      ManY = ManY + 2

    END IF

    IF LeftOn = -1 AND RightOn = 0 AND PManLeftTopLeft = 0 AND PManLeftMiddleLeft = 0 AND PManLeftBottomLeft = 0 THEN

      IF ManX > ViewX1Limit + 160 AND ManX < ViewX2Limit - 158 THEN ViewX1 = ViewX1 + 2: ViewX2 = ViewX2 + 2

      ManX = ManX - 2

    END IF

    IF RightOn = -1 AND LeftOn = 0 AND PManRightTopRight = 0 AND PManRightMiddleRight = 0 AND PManRightBottomRight = 0 THEN

      IF ManX > ViewX1Limit + 158 AND ManX < ViewX2Limit - 160 THEN ViewX1 = ViewX1 - 2: ViewX2 = ViewX2 - 2

      ManX = ManX + 2

    END IF


    ' reset timer and display graphics

    GameSpeed = 0


    _DISPLAY

  END IF


  ' Loop here until an even amount of time has passed

  DO

  LOOP UNTIL PEEK(1132) >= 1

  DEF SEG


  ' Increment the timer

  GameSpeed = GameSpeed + 1


LOOP


END



SUB DrawImages


' Clear the screen and draw each tile one at a time

LINE (0, 0)-(319, 199), 0, BF

FOR DrawTile = 0 TO 9

  IF NOT (TileX1(DrawTile) + ViewX1 > 320 OR TileX2(DrawTile) + ViewX2 < 320 OR TileY1(DrawTile) + ViewY1 > 200 OR TileY2(DrawTile) + ViewY2 < 200) THEN

    LINE (TileX1(DrawTile) + ViewX1, TileY1(DrawTile) + ViewY1)-(TileX2(DrawTile) + ViewX1, TileY2(DrawTile) + ViewY1), 6, BF

  END IF

NEXT DrawTile


' Draw the Man (Ball in this case)

CIRCLE (ManX + ViewX1, ManY + ViewY1), 19, 10
CIRCLE (ManX - 1 + ViewX1, ManY - 1 + ViewY1), 19, 10
PAINT (ManX + ViewX1, ManY + ViewY1), 10, 10


END SUB


Cheers,
Justin
« Last Edit: June 23, 2012, 07:23:54 AM by JustinRichardsMusic »
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

OlDosLover

  • Hero Member
  • *****
  • Posts: 3907
  • OlDosLover
    • Email
Hi all,
    Will looky over this. Thank you for sharing!!!!
OlDosLover.

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2268
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Yeah, thanks :)

This is interesting.

Robert Claypool

  • Newbie
  • *
  • Posts: 45
    • Email
IT dosn't use bitmapts though... It's all a bunch of solids done with LINE statements.

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2268
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
IT dosn't use bitmapts though... It's all a bunch of solids done with LINE statements.

Simply substitute sprites at the upper left x,y coordinates.

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
IT dosn't use bitmapts though... It's all a bunch of solids done with LINE statements.

I'm working on a game using this engine that has nice graphics. It has been setup using an array of tiles to create the background. You could easily import graphics into the program using any number of methods and place them where the line statements are.

The focus of this example is not graphics but the engine itself. It seems simple, and there a several ways to accomplish it, but using this method you can still find each tile and sprites position relative to the players position without error.
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

OlDosLover

  • Hero Member
  • *****
  • Posts: 3907
  • OlDosLover
    • Email
Hi all,
    Its a good effort JustinRichardsMusic and a worthwhile addition for the community. I thank you for your contribution! It runs fine!
OlDosLover

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
I will post a more graphical version soon to give people a better idea of its usefulness. I downloaded a SNES emulator and have been "researching" (in other words playing) some of the games that had this style of game engine to get some inspiration.

Cheers,
Justin
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
I have attached a new version of the View Portal Engine with graphics this time so that people can see what it was actually designed for...

INSTRUCTIONS:

Download View Portal 2.zip and Unzip to your QB64 Directory.
(The program should run either in its own directory or from the main directory)

Open ViewPortal2.bas and Compile... (That's it  ;))

OPTIONAL:

Open Grafix.bas and Compile... (Use this to create the graphics for the game, try loading "GreenBrickTop.gfx")


If anyone has trouble running or understanding the code please post back and I will be  glad to help :)

Cheers,
Justin
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
Did anyone have trouble unzipping this?  I tried on my work machine and noticed that because of the spaces in the .zip file name I get a directory like this "\View+Portal+2\" when I unzip it.  If it was run from this position it would result in an error retrieving the image files.
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

OlDosLover

  • Hero Member
  • *****
  • Posts: 3907
  • OlDosLover
    • Email
Hi all,
    Yes. It created "View Portal2\View Portal2\Resources" which is one "View Portal2" too many. And of course it errored out. Moving the contents up one folder solved the problem. I  must say VERY NICE graphics and a pretty smooth demo that is well worth the look. This is a REALLY good effort that should garner some attention in my opinion. Once again thanks for sharing and WELL DONE on a valuable community addition!
OlDosLover.

Cyperium

  • Hero Member
  • *****
  • Posts: 3299
  • Knowledge is good, but understanding is better
    • Cyperium
    • Email
There wasn't any problems for me when extracting it.


Nice engine and good graphics, looking forward to see more of this!

fatman2021

  • Hero Member
  • *****
  • Posts: 978
  • Lord Jesus Christ, Son of God, have mercy on us.
    • Email
I am interested in developing a clone of the the 3DS version of The Legend of Zelda Ocarina of Time.
Woe to those who call evil good, and good evil;
Who put darkness for light, and light for darkness;
Who put bitter for sweet, and sweet for bitter!

Isaiah 5:20

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 337
  • Character names can be found in metal from the 90s
    • Email
Thanks for the info guys, I appreciate it!

Fatman, you do realise that the 3ds version of Zelda has no similarities to the SNES version apart from the Name???

The 3DS version is a full 3D mapped, textured, lit, rotating, etc, environment with fairly high-res graphics.

The SNES version is a simple 2D map with interactive sprites and 16-bit graphics.

If you have made a start on some code and would like some suggestions then post the code and I'll take a look.  Otherwise 3D games aren't on my agenda at the moment, sorry :(
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

Johny B.

  • Sr. Member
  • ****
  • Posts: 487
    • Email
There was also the N64 version, which was 3D.
"Time is an illusion; Lunchtime doubly so." - Douglas Adams