Jump to content

  • Log In with Google      Sign In   
  • Create Account

[java] Questions about scrolling engine


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Captain Goatse   Banned   -  Reputation: 100

Like
Likes
Like

Posted 20 March 2000 - 08:12 PM

Right now I have charachter who can walk on map image. I have limited the walking aea to 96 pixels from every edge and now I have been thinking about how to make it scroll. Because my game is turn based my character jumps from tile to tile. I used to have some scrolling but it was way too slow and I didn''t know way to optimize it up so I decided to post here. What should I do? Should I draw everything to one bigger map image and then show part of it or what. If so can you give me example or something? Time comes, time goes and I only am.

Sponsor:

#2 chippydip   Members   -  Reputation: 122

Like
Likes
Like

Posted 20 March 2000 - 08:49 PM

Someone correct me if I''m wrong, but I think you are on the right track about saving a map image. I think you would get the best performance if you made the map once on a *large* surface and then just Blt the part that is visible at the moment. This isn''t really feasable on a decent sized map, so the next best thing is to save part of the map. The best way to go, i believe, is to save the map image from the last frame (before adding any of the characters or other non static overlays) and then use as much of this image for the next frame as possible. In the best case, the screen won''t scroll and you will have your map image already. In the worst case you will have to scroll it by a tile or so horizontaly and vertically so you will have to update a row and a collumn of tiles (but the rest can just be shifted.

You might even be able to skip a temp surface and just use the data in the backbuffer from 2 frames ago... clearing the stuff that has changed, etc. but this would be much more complicated to keep track of I think, so a temp surface is probably the way to go.

#3 Ingenu   Members   -  Reputation: 930

Like
Likes
Like

Posted 20 March 2000 - 09:55 PM

If you''re using a tile engine, it''s not very hard to do scrolling. You just have to rewrite the whole scene decaling it from 2 or more pixels.
You''ll have a nice smooth scrolling.
You should make a ''free'' zone in which the character can move and there''s no scrolling. When the character comes close a side, the scrolling begin, speeding up as it''s closer to the side.
Of course, it must be a blocked area where the sprite can''t go.
After the character has moved, the screen recenter on it, with the same process.
(Fast when he is far from the center, slower when he get closer)

-* Sounds, music and story makes the difference between good and great games *-

#4 Ingenu   Members   -  Reputation: 930

Like
Likes
Like

Posted 20 March 2000 - 10:02 PM

oups, sorry didn''t see it''s for turned based game.

You just have to redraw the scene (each tile) with Xpixels decaling.
Use tripple buffering to improve performance.
Tiling is most effective in term of speed and memory usage.
Big BMP/anything (just like in Baldur''s Gate) require very fast compiled code, or hardware acceleration.

You''re character might move during the time you''re redrawing the map, such everything will be in movement.

Optimizing is as said by chippydip to save the previous image, compute the changes, redraw what''s required, blit it with Xbits decals and then redraw ''objet'' & ''character'' layers, if you have such.

Hopes it help, if you feel I''ve not well explain, just mail me, I''ll to try again :o)

-* Sounds, music and story makes the difference between good and great games *-

#5 Jim_Ross   Members   -  Reputation: 122

Like
Likes
Like

Posted 21 March 2000 - 03:01 AM

This is just the way I do it. I have a linked list of all the tiles on my map. I make sublists that represent horizontal rows of the map each being two tiles longer than the map. I also make two more rows than necassary. This gives me a one tile cushion around the whole outside. So only the data from the sublist rows gets painted each cycle. The problem I have is deciding when to redefine those sublists, but that''s because my game is not turn based, it''s free flowing. Right now I calculate the sublists every draw cycle and it seems to run fine on my 300MHz machine. I think I will keep a running tab of how many pixels the player has scrolled, and if it''s greater than the size of one of my tiles, reload the sublists.

#6 Captain Goatse   Banned   -  Reputation: 100

Like
Likes
Like

Posted 21 March 2000 - 03:54 AM

Ok I barely got the main idea so what modifications should be done to this example from JDGC:

/*
MapTest.java
a demo of a simple tile map
the red focus is arrow key controllable
*/
//**************************************************
// COPYRIGHT & LEGAL NOTICE
// This source code copyright 1998 Grey Creations, Ltd.
// Non-commercial, personal use is permitted.
//
// This file is not to be posted in a public space or distributed
// in any form without prior consent.
//
// The Author and Grey Creations, Ltd. make no warranty of any kind, expressed or implied,
// with regard to this program. The Author and Grey Creations, Ltd. shall not
// be liable in any event for incidental or consequential damages in
// connection with, or arising out of, the furnishing, performance, or
// use of this program.
//
// If you find this useful please let me know: grey@panix.com
// Thanks for helping to make the Java Game Development Center great!!!
//**************************************************

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;

public class MapTest extends Applet {

MapView map;

CellImage testImage; // the multi-cell image with the terrain pics in it

public void init() {
setLayout(null);
//setBackground(new Color(0,0,0));

// specify your image info here
testImage = new CellImage(this, "grass1.gif", // put your filename here
new Dimension(32, 32), // cellSize in pixels
new Dimension(1, 6), // cellLayout -- how many cells across and down
6); // how many actual cells there are (in case you don''t fill the image)

// this holds the terrain data to pass to the map
// we''ll make an 8x6 map
// the numbers correspond to cells in the testImage
int[][] tArray = {{0, 1, 0, 1, 0, 1, 0, 1,0},
{4, 5, 4, 5, 4, 5, 4, 5,0},
{0, 1, 0, 1, 0, 1, 0, 1,0},
{2, 1, 4, 5, 4, 5, 4, 5,0},
{4, 5, 2, 3, 1, 0, 1, 0,0},
{2, 3, 2, 3, 3, 2, 3, 2,0},
{2, 3, 2, 3, 3, 2, 3, 2,0}
{2, 3, 2, 3, 3, 2, 3, 2,0}};

// create the map
map = new MapView(tArray, testImage);
add(map);

addKeyListener(map);
//repaint();
Button au= new Button("Au");
au.setBounds(50,50,300,200);
add(au);
}

public void start() {
map.requestFocus();
}

public void update(Graphics g) {
paint(g);
}

public void paint(Graphics g) {
map.paint(g);

}


} // end of applet


class MapView extends Canvas implements KeyListener {
Dimension mapSize = new Dimension(); // the actual size in pixels of the map component
Dimension mapLayout = new Dimension(); // how many cells across and down to display
Dimension cellSize; // width / height of a map tile
CellImage mapTiles; // the terrain tiles

public int focusX = 0; // which tile gets the hilite
public int focusY = 0;

Point viewOrigin = new Point(0, 0); // which map space corresponds to the upper left tile of the view

int terrainArray[][]; // integer representation of map

Point paintXY = new Point(); // where to paint each terrain tile

public MapView(int aTerrainArray[][], CellImage aMapTiles) {
super();
terrainArray = aTerrainArray;
mapLayout.width = terrainArray[0].length;
mapLayout.height = terrainArray.length;
mapTiles = aMapTiles;
cellSize = mapTiles.getCellSize();
mapSize.setSize(mapLayout.width * (mapTiles.getCellSize().width),
mapLayout.height * (mapTiles.getCellSize().height));

addKeyListener(this);
requestFocus();
}

// override necessary functions for Canvas class
public Dimension getSize() { return mapSize; }
public Dimension getPreferredSize() { return mapSize; }



public void setFocusTile(Point p) {
focusX = p.x;
focusY = p.y;
}



// draw the entire map
public void paint(Graphics g) {
g.setColor(Color.red);
for(int y = 0; y < mapLayout.height; y++)
for(int x = 0; x < mapLayout.width; x++) {
paintXY.setLocation(x * cellSize.width, y * cellSize.height);


// notice that x, y are reversed here because
// that is how the arrays are specified
mapTiles.paint(g, paintXY, terrainArray[y][x]);
}
// reset the clip rectangle from the map draw operation
g.setClip(0, 0, mapSize.width, mapSize.height);
// draw the focus
g.drawRect(focusX * cellSize.width, focusY * cellSize.height,
cellSize.width-1, cellSize.height-1);
}


public void keyPressed(KeyEvent ke) {
switch(ke.getKeyCode()) {
case KeyEvent.VK_RIGHT: focusX++;
break;
case KeyEvent.VK_LEFT: focusX--;
break;
case KeyEvent.VK_UP: focusY--;
break;
case KeyEvent.VK_DOWN: focusY++;
break;
}
// check bounds
if(focusX < 0) focusX = 0;
if(focusY < 0) focusY = 0;
if(focusX > mapLayout.width - 1) focusX = mapLayout.width - 1;
if(focusY > mapLayout.height - 1) focusY = mapLayout.height - 1;
getParent().repaint();
}

public void keyReleased(KeyEvent ke) { }
public void keyTyped(KeyEvent ke) { }

}


class CellImage {
// parent applet
Applet mom;

// how many cells across and down (col/row) in layout
Dimension cellLayout;

// the dimensions of a single cell
Dimension cellSize;

int numCells; // The number of cells in the image

Image image; // the master image that holds all the cells

int curCellNum = 0; // which cell to paint on request

// pass Applet context, Image filename, width/height of a cell,
// how many cells fit across and down the image,
// and how many actual cells there are to display
public CellImage(Applet aMom, String imgName, Dimension aCellSize, Dimension aCellLayout, int aNumCells) {
mom = aMom;
cellSize = aCellSize;
cellLayout = aCellLayout;
numCells = aNumCells;

image = mom.getImage(mom.getCodeBase(), imgName);
}

public Dimension getCellSize() { return cellSize; }
public int getNumCells() { return numCells; }


public void paint(Graphics g, Point p, int cellNum) {
curCellNum = cellNum;

// paint which cell #?
int iNum = cellNum;

// check for overflow
if(iNum > numCells - 1) {
curCellNum = 0;
// paint gray
g.setColor(Color.darkGray);
g.fillRect(p.x, p.y, cellSize.width-1, cellSize.height-1);
} else {

// where to paint cell
int userX = p.x;
int userY = p.y;

// locate the cell to paint
int col = iNum % cellLayout.width;
int row = iNum / cellLayout.height; // width?

// this is the amount to shift the entire source image
int offsetX = - (col * cellSize.width);
int offsetY = - (row * cellSize.height);

// set clipping rect to cell size at specified location
g.setClip(userX, userY, cellSize.width, cellSize.height);

// paint into graphics context
if (image != null)
g.drawImage(image, userX + offsetX, userY + offsetY, mom);
}
}
} // end cellImage

Ok first I should of course make the screen let''s say 96x96 area which is rather easy but what then? I''m completely out of ideas...


#7 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 21 March 2000 - 04:21 AM

I''ll start with the beginning.
Load your map.
Init the game, and draw the complete image.
You must know where you stand in the world map, and knowing where the edges lies (because you know the screen size) you know to which tiles it is corresponding.
When the player moves, copy the front to the back, with X pixels decals, and then read the borders tiles and draw them where they must.
repeat this step as required.
When you change map, you have to re init and draw it a first time.

I''m busy and tired, that''s why I''m not giving code solution.

-* Sounds, music and story makes the difference between good and great games *-

#8 Ingenu   Members   -  Reputation: 930

Like
Likes
Like

Posted 21 March 2000 - 04:21 AM

I''ll start with the beginning.
Load your map.
Init the game, and draw the complete image.
You must know where you stand in the world map, and knowing where the edges lies (because you know the screen size) you know to which tiles it is corresponding.
When the player moves, copy the front to the back, with X pixels decals, and then read the borders tiles and draw them where they must.
repeat this step as required.
When you change map, you have to re init and draw it a first time.

I''m busy and tired, that''s why I''m not giving code solution.

-* Sounds, music and story makes the difference between good and great games *-




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS