I whipped up something in a hurry (So it prolly isn't coded in the best way possible) but maybe it'll give you a visual clue. I think at 2000x1200 pixels, it becomes a question of both your specs and your target-user's specs. My laptop can handle it with up to 150 entities before dropping a single frame below 60fps, but that's my machine and not your audience's. Also, Zenassem's method with the tiles may be a little more user-friendly in terms of logic (Square used a similar methodology in FF4 and FF5 and then a complicated version in FF6 on SNES. I dunno abt the NES ones, I and II look like 2 layers, III is hard to tell because of some clever effects but I'd say at least 4.)
remstart
Example of basic dungeon-crawler skeleton.
Running at only 800x600, you'll easily get 60 FPS per map. I ran it fine on my laptop.
Laptop Specs:
ATi HD 5470 with 512MB dedicated GDDR3 VRAM
Core i5-430M 4 x 2.27 GHz
4MB DDR3 RAM 1033
Win7 HP x64
The FPS may be a little erratic by up to 5 frames more or less than your framerate. Won't affect anything visually.
If you're worried about resources, you can break your map into sections or stick with tiles.
This is just a rough concept. There's lots of things here you wouldn't do in your game, such as not using UDTs, etc.
It's more for learning purposes than actually making a game with, but you could prolly use the basic framework.
Before running, you need to fill in the section marked "BEFORE RUNNING CODE..."
Up, Down, Left, Right move your character, ESC exits.
Would have included a HowTo on collision and using tiles but I don't have time because the holiday madness has already
gripped me in it's teeth and ALL the relatives are on my case. Anyhow, sure someone else will post some code if you need
it.
I formatted this like a text book, well tried to, it looks a little childish when I look at it now. Oh well...
remend
`Declarations
#CONSTANT bg 99 `For storing Background image
#CONSTANT Player1 98 `For storing Player image
#CONSTANT bglayer 20 `These are layers (What Zenassem was talking about). For this example, we use three.
#CONSTANT entlayer 40 `The higher the number, the lower its layer. "entlayer" would be entities like rocks, players, walls, etc.
#CONSTANT toplayer 60 `Refer to the SET SPRITE PRIORITY in the proceeding code.
GLOBAL MyBG$
GLOBAL MyFPS
GLOBAL MyEntity$
GLOBAL MyPlayer$
GLOBAL speed
`BEFORE RUNNING CODE, fill in the following
MyBG$ = "" `<---- Fill in your background image here
MyPlayer$ = "" `<---- You'll never guess what this is for (Your player's image)
MyFPS = 60 `<---- Your Frame per Second rate goes here
speed = 2 `<---- Number of pixels per cycle you want it to move
` You can achieve a slower rates than 1 by adding timers using the TIMER() command.
`Code
SYNC RATE MyFPS `<---- Comment this out if you want to see how fast your system can run XD
SET DISPLAY MODE 800, 600, 32
`I'm just doing things the quick and lazy way here
CREATE ANIMATED SPRITE bg, MyBG$, 1, 1, bg
CREATE ANIMATED SPRITE player1, MyPlayer$, 1, 1, player1
`Sprite background and center it.
SPRITE bg, (SPRITE WIDTH(bg) - SCREEN WIDTH()) / -2, (SPRITE HEIGHT(bg) - SCREEN HEIGHT()) / -2, bg
SPRITE player1, (SCREEN WIDTH() / 2) - (SPRITE WIDTH(player1) / 2), (SCREEN WIDTH() / 2) - (SPRITE WIDTH(player1) / 2), player1
`You don't need to in this example but you should make a habbit of doing this when you work with sprites.
`It also illustrates something.
SET SPRITE PRIORITY player1, entlayer `I'v set the player to the same layer as entities; 40
SET SPRITE PRIORITY bg, bglayer `Background, gets the background layer
`BTW, I set the layers apart by 20 so you can use "layer-between-layer" effects
`such as multiple backdrops in a 2D sidescroller or overlays, eg:
`SET SPRITE PRIORITY overlay, bglayer + 1
`That would place a layer above the backdrop without interfering with the "entity layer"
`Mainloop
DO
fprate$ = "Current Frames per Second: " + STR$(SCREEN FPS()) + " of " + STR$(MyFPS) + " (Desired FPS)"
SpriteText(20, 20, fprate$, 9999, 999)
PlayerInput()
LOOP
`Functions
Function PlayerInput()
`Check what keys/mouse/other device input have been made, act accordingly.
IF UPKEY() = 1
`It's easy to get y-axis confused and place a - instead of a +.
SPRITE bg, SPRITE X(bg), SPRITE Y(bg) + speed, bg
`Insert animation for player, etc.
ENDIF
`I'm using one line for the rest because it's a SIMPLE example. Don't do it if it's complicated or you'll suffer with debugging
IF DOWNKEY() = 1: SPRITE bg, SPRITE X(bg), SPRITE Y(bg) - speed, bg: ENDIF
IF RIGHTKEY() = 1: SPRITE bg, SPRITE X(bg) - speed, SPRITE Y(bg), bg: ENDIF
IF LEFTKEY() = 1: SPRITE bg, SPRITE X(bg) + speed, SPRITE Y(bg), bg: ENDIF
EndFunction
Function CollisionCheck()
`Check collisions here.
EndFunction
Function SpriteText(x, y, txt$, SpriteNo, Priority)
`This creates a small overlay message for things such as HP/MP etc.
`It is NOT ideal for large quantities of text. I actually have a much
`better function like this somewhere.
IF localtext$ <> txt$
IF BITMAP EXIST(30) = 0: CREATE BITMAP 30, LEN(txt$) * 16, 20: ENDIF
SET CURRENT BITMAP 30
CLS
PRINT txt$
localtext$ = txt$
GET IMAGE SpriteNo, 0, 0, BITMAP WIDTH(30), BITMAP HEIGHT(30), 1
SET CURRENT BITMAP 0
SPRITE SpriteNo, x, y, SpriteNo
SET SPRITE PRIORITY SpriteNo, Priority
ELSE
SPRITE SpriteNo, x, y, SpriteNo
SET SPRITE PRIORITY SpriteNo, Priority
ENDIF
EndFunction
Anyways, tiled, or not tiled, I'm sure you can draw something useful from this. Btw, if your collisions don't need to be accurate, then just use DBPro's sprite collision command. It's not half bad actually.
@MrValentine:
Quote: "Urm... how about ray casting? Or is that what you meant zero?"
I meant 2D vector collision. Brief summary: If a sprite collision is detected, check if either of the four corners (depending what side of the vector line they're on) of the sprite is between a set of 2D vector lines (which are technically fake as they're in pixels), return a a positive value for collision. Different boundaries can be set for different enemies to accomodate the player's bounding box and larger player characters can have more collision points. Usually no more than 3 down each side is needed. It's hard to explain in words, but it worked quite well in the last 2D shooter I made.