Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by Elvar

Hey fellow impactors!

I've read almost all threads that even begins to come close to my challenge, and I haven't exactly gotten any closer.. maybe it's me thats just having trouble understanding how to implement the current suggestions for RTS like screen scrolling, but never the less, I have a problem :-) I hope you guys can help me out.

Now, it's been some time since me and my buddy were in here getting help from you guys, but we've decided to continue our tower-defense game, we began in the summer of '12.

A little about the project:
Its a multiplayer Tower Defense game called Fantasy TD (MOTD). We have a client version of impact, and have rewritten impact, to sooth our server version needs. We then use socket.io to synchronize the server with the client which, for now, works fine.

My challenge is:

I have a canvas with a resolution of 880 x 500, with a scale of 1, running at 60 fps.
I have a map with a resolution of 3000 x 3000

#1.) I want to be able to fix the canvas (the open window to the map) to begin where ever i choose based on some data, (eg. If red player has the client, he begins at red monster spawn, and so on)

#2.) I want to be able to bind left, right, up and down arrow keys to scroll around in the map, until it reaches end of map in either side. (I do not want to follow an entity like player or anything, like the camera does), I simply just want to move the map around.


Can someone help me? I'm desperate :-) thaankss

1 decade ago by Joncom

You could still use the camera.js entity that's on the download page. Just instead of following the player, have it take input from the keyboard.

Something like:

update: function() {
    if(ig.input.state('left')) ig.game.screen.x -= 60; // move screen left
    else if(ig.input.state('right')) ig.game.screen.x += 60; // move screen right
    // etc.
}

For number 2, I'm not sure if you're asking how to bind keys. If so, this will be helpful.

1 decade ago by Elvar

Thanks for the reply Joncom... I have tried something... but I'm not quite sure how to get it working exactly like i want it to..

I'm using the scrollScreen i found on point of impact..

  if( ig.input.mouse.x  > (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width/2) ) {
    this.screen.x = ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width;
  } else if ( ig.input.mouse.x  < ig.system.width/2 ) {
    this.screen.x = 0;
  } else {
    this.screen.x = ig.input.mouse.x - ig.system.width/2;
  }

  if( ig.input.mouse.y > (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height/2) ) {
    this.screen.y = ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height;
  } else if ( ig.input.mouse.y  < ig.system.height/2 ) {
    this.screen.y = 0;
  } else {
    this.screen.y = ig.input.mouse.y - ig.system.height/2;
  }

This moves the map according to the mouse and stops when map ends at either point, ( left, right, up down..) with no black background surrounding the map indefinately.. which is almost what i want.. but..

I want to like you Jancom described.. with the state, to push the screen around accordingly..

      if(ig.input.state('left')) this.screen.x -= 30; // move screen left
      else if(ig.input.state('right')) this.screen.x += 30; // move screen right
      else if(ig.input.state('up')) this.screen.y -= 30; // move screen up
      else if(ig.input.state('down')) this.screen.y += 30; // move screen down

What I mean to say is.. I can create the bounderies if I have a concrete "object to measure against.. "mouse" fx.. but what if i want the scrolling/moving to stop at end of map using my inputs, how do I set the boundaries?

Please help me :-) Thank you

1 decade ago by mLautz

You can check the position of the screen relative to the game. If you also know your window size, you can use the two to check that the screen does not leave the map.

if(ig.input.state('left') && !this.screen.x<=0){
    if(this.screen.x > 30){
        this.screen.x -= 30;
    }else{
        this.screen.x = 0;
    }
}

I believe something like this should stop the camera from leaving the left edge. To check your right edge, you would need something like below:

if(ig.input.state('right) && !this.screen.x >= ig.game.backgroundMaps[0].pxWidth - this.screenWidth){
    if(this.screen.x < ig.game.backgroundMaps[0].pxWidth - this.screenWidth - 30){
        this.screen.x += 30;
    }
    else{
        this.screen.x = ig.game.backgroundMaps[0].pxWidth - this.screenWidth;
    }
}

The example code may not be perfect, but it should demonstrate the point that you want to check your screen position relative to the size of one of your maps and take into account the screen width/height.

1 decade ago by Elvar

What do you mean by screen width/height?.. The first snippet was very useful thank you.. it works now with "up" and "left" arrows.. and stops scrolling at map end both at left and at top.. but.. I still can't figure out which properties to calculate from when i do what you suggest?.. I used the system width and height to try it out.. but i still just keep scrolling into blackness both at down and right.. The second suggestion was hard for me to implement, can you help me more on the way perhaps?..

1 decade ago by mLautz

The second code snippet I posted was a bit from a game I had written where the camera follows the player, and that is part of the code that stops the camera from going off screen.

I wish I could draw you a picture to demonstrate this, but I'll see if I can explain it better.

The main objective here is to keep the camera within the bounds of your level. The dimensions of your level can be defined by the collision (physical boundary) or background map (visual boundary) you create the level with.

With that information in mind, you can define the four boundaries of your level like this:
Left Boundary (Vertical): Occurs at x = 0
Top Boundary (Horizontal): Occurs at y=0
Bottom Boundary (Horizontal): Occurs at y=0 + the height of your level
Right Boundary (Vertical): Occurs at x=0 + the width of your level

Building on this information, you know that your screen (window into the level) has a fixed height and width of its own. In order to keep the right side of your screen from leaving the level, you have to make sure that the left side of your screen + the screen width <= the right boundary.

In my code excerpt, my "this.screenWidth" and "this.screenHeight" were defined as ig.system.width and ig.system.height. So I'm not really sure why those wouldn't work when you tried them....

Hopefully by explaining it, you might be able to figure out what is wrong since I can't test a coded solution right now. Best of luck!

I might be able to churn out a working demo tonight/tomorrow if you still need some help later. (Would make a decent blog post I guess)

1 decade ago by mLautz

@Elvar, I totally forgot! I was using a plugin to simplify getting the map height and width..

Originally found here: Map Size in Pixels

Demo Here: Arrow Key Screen Scroll

Code Here: Arrow Scroll Demo Source

1 decade ago by Elvar

Well I followed your thinking, I think.. I got it to work YAY.. Thank you very much for your time and energy spend on meh ^_^..

What is does is simply to stop at what end when the map ends.. then i have bound the keys for that purpose and voila..

    scrollScreen: function() {

      // Camera Movement Speed in pixels per update while input is in state
      // 5 pixels movement 60 times per second = 300 pixels/second
      var cameraMoveSpeed = 5;

      if(ig.input.state('left')) this.screen.x -= cameraMoveSpeed; // move screen left
      else if(ig.input.state('right')) this.screen.x += cameraMoveSpeed; // move screen right
      else if(ig.input.state('up')) this.screen.y -= cameraMoveSpeed; // move screen up
      else if(ig.input.state('down')) this.screen.y += cameraMoveSpeed; // move screen down

      // Left scroll - make sure it stops when the map stops.. map x start
      if(ig.input.state('left') && !this.screen.x <= 0) {
        if(this.screen.x > cameraMoveSpeed) {
          this.screen.x -= cameraMoveSpeed;
        }
        else {
          this.screen.x = 0;
        }
      }
      // Up scroll - make sure it stops when the map stops.. map y start      
      if(ig.input.state('up') && !this.screen.y <= 0) {
        if(this.screen.y > cameraMoveSpeed) {
          this.screen.y -= cameraMoveSpeed;
        }
        else {
          this.screen.y = 0;
        }
      }
      // (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width) is end of map.. FOR X / WIDTH
      if(ig.input.state('right') && !this.screen.x <= (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width/2) ) {
        if(this.screen.x < (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width) ) {
          this.screen.x += cameraMoveSpeed;
        }
        else {
          this.screen.x = (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width);
        }
      }
      // (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height) is end of map.. FOR Y / HEIGHT
      if(ig.input.state('down') && !this.screen.y <= (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height/2) ) {
        if(this.screen.y < (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height) ) {
          this.screen.y += cameraMoveSpeed;
        }
        else {
          this.screen.y = (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height);
        }
      }
    }

Put it in main as a function, and just called it in main update like the following:

    update: function() {
      // Call camera function
      this.scrollScreen();
    },

It actually works and it seems quite smooth, but if you or anyone else have a better solution, I'm open for suggestions...
Thanks again for your time and guidance, couldn't have done it without you!

1 decade ago by mLautz

Glad you got it working :) I like troubleshooting, and it gave me a reason to make a blog post :D

If you check out the source code I posted on gist (above), I managed to eliminate some of the IF statements. I started with a few too many...

And nice job figuring out to multiply the map dimension by the tile size. I was using a plugin to do that for me.
Page 1 of 1
« first « previous next › last »