Newbies Questions - Parallax Scrolling, Camera, Cursor Modes, GUI

Started by bulka_tarta, Sat 28/01/2017 19:28:58

Previous topic - Next topic

bulka_tarta

Hi,

Sorry for the second thread, but I wasn't sure if it would be best to continue under the first one, or to create a second one.
I'm also sorry for putting multiple questions/problems in the same thread but splitting them up into couple various ones seemed unappropriated.

I'm trying to set up a bunch of features before I start creating all the rooms, items and puzzles for the game.
The way I usually work is that if I get stuck way too long on one thing, I move onto something else, so I can come back to the first problem later with a fresh approach (hence I "generated" so many questions).

Here's what I have been struggling with:

1) [SOLVED] Cursor Modes - I'm planning on using two clicks instead of Coin Verb etc.
I already found all the scripts and help on the forum and I got everything working. However, I'm also using the Parallax and Smooth Camera module, which complicates things a little bit. The problem is that the cursor changes depending if it's on hotspot or object. To have some Parallax layers on top, I'm using objects on the background that I don't want the player to interact with (e.g. trees in the front, mountains in the back). I couldn't find another way for the Parallax effect to work, so I'm trying to get the object's PxPos in order to determine if the cursor should change.

Code: ags

void UpdateMouseGraphic() {
  if (player.ActiveInventory != null) return; // do nothing
  int newGraphic = 30;  // no location / walking
  int lt = GetLocationType(mouse.x, mouse.y);
  //  ORIGINAL: if (lt == eLocationHotspot || lt == eLocationObject) newGraphic = 27;
  if (lt == eLocationHotspot) newGraphic = 27;  // interact                            
  if (lt == eLocationObject && (object[0].GetProperty("PxPos") == 0)) newGraphic = 27;   // if it's an object AND it's PxPos property is 0 (no parallax)
  else if (lt == eLocationCharacter) newGraphic = 27;  // talk
  // change?
  if (newGraphic != mouse.GetModeGraphic(mouse.Mode)) mouse.ChangeModeGraphic(mouse.Mode, newGraphic);
}


Problem with the above is that I'm only limiting myself with object[0], whereas I want to check "all the objects".
I have tried multiple different variants, but I can't get it to work.

----------
2) A general question with Parallax objects. Do they have to be "objects"? Is there a different way to set it up? Any best practice?

----------
3) Camera - My backgrounds currently are quite tall, and the camera always centers on the main character. In some places, I want the camera to be higher up, to show the background a little bit better. I have currently created a cDummy character which is attached to main hero. I placed the Dummy slightly higher than the main character, so I kind of have the camera a little higher up. However, it's not perfect, and depending on different positions of the character I get different results with the camera - I can't control it that well.

Is there a way to keep the main character within the lower 1/3 of the screen?

----------
4) [SOLVED] Book GUI - I wanted to have a book in the game, where player can read-through (well, look at some images), which later helps solve some of the puzzles. My current approach was based on Densming's tutorial on List Boxes. I have a GUI background, two buttons at each side of the book (for flipping through the pages) and a large button that overlays the background. The idea was that when you press the left/right button, the image on the large one would change, imitating flipping through the pages.

I thought I could have a function that keeps track of the variable, and depending on it, it would change the picture. I was thinking that the buttons (left and right) could add or subtract the variable, thus changing pages.

Something like this:

Code: ags
function BookPage(int bp){
 
 if (bp == 0){
   bBookPage.NormalGraphic = 33;
 }
 else if (bp == 1){
   bBookPage.NormalGraphic = 34;
 }
 else if (bp == 2){
   bBookPage.NormalGraphic = 35;
 }


}


And later the buttons:
Code: ags

function bTurnRight_OnClick(GUIControl *control, MouseButton button)
{
  BookPage(+= 1);
}


Although the above doesn't give me any errors, it also doesn't do anything in the game at all. I went through all of the tutorials, and it all makes sense when shown with examples, but when I try to apply anything to my own script I just keep asking myself questions "what if, why is that etc." and I can't get anything to work.

From what I understand, each of this tasks is relatively simple, but I am new to programming, hence I thought that the best way to start learning would be with AGS. Any kind of help would be appreciated, even pointing in the right direction (e.g. link to a similar problem) would be great!

dayowlron

My Mistake...

Calling BookPage with a parameter of (+= 1) always passes in a 1.
You need to have a variable to store the current setting then add 1 to it before passing the variable in.

Change the function to:

Code: ags

int bp;
function BookPage(){
 
 if (bp == 0){
   bBookPage.NormalGraphic = 33;
 }
 else if (bp == 1){
   bBookPage.NormalGraphic = 34;
 }
 else if (bp == 2){
   bBookPage.NormalGraphic = 35;
 }
 
 
}

function bTurnRight_OnClick(GUIControl *control, MouseButton button)
{
  if (bp<2) bp++;
  BookPage();
}

function bTurnLeft_OnClick(GUIControl *control, MouseButton button)
{
  if (bp>0) bp--;
  BookPage();
}

Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

dayowlron

My previous response was in reference to your #4 issue. In response to your #3 issue There is a command "SetViewPort" you can use. look it up in the manual and you can set it in the repeatedly_execute function. As far as issues #1 and #2, I don't know how to help with that.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

bulka_tarta

That is great, works like it should. Thank you very much!

I'm just curious about few things: so the variable needs to be above (and outside) the function, so the "int" can be accessed throughout?
Also, why should it be like:

Code: ags

if (bp<2) bp++;
  BookPage();


I would have thought that the first line would be enough, or I would have put the "BookPage();" first, assuming that the second line would be a follow up to the function. I'm not questioning your approach, it's just something I haven't picked up from the tutorials, and I'm simply wondering why things are the way they are. :)

Thanks again!


Oh and I will check out the "SetViewPort" in the repeatedly_execute function. Awesome :)

bulka_tarta

Sorry for the double post.

I was working on attaching the book to it's GUI, and I found a solution to issue #1.
Turns out the solution was super easy. In the "Design" section of the object, there's a "Clickable" function. Turning it to "false" solved the problem and the cursor is no longer changing in the game, which is exactly what I wanted for the parallax objects.
It works perfect and it's simple enough to do for each parallax object in the future, unless there's some "hidden" disadvantage of making these objects unclickable?

EDIT:
I looked around the forums some more, and I have hacked together something like this:
Code: ags

  int yCoord = (GetViewportY()-30);
  SetViewport(GetViewportX(), yCoord);


Partially, the code above is what I was after. It offsets the viewport just enough so that the character is in the lower part of the screen.
However, there are two problems with this, and I have no idea how to approach them.
Problem 1) When I hover over the GUI on the top of the screen, the viewport jumps a lot higher than it was originally. I have some ideas on how I could fix this, so I will work on this some more.
Problem 2) Is a little more complicated. The screen being a little bit higher than the original introduces a problem when scrolling downwards. E.g. lets say you have a ladder in the game. When I go upwards, the camera nicely scrolls and the character is kept in the lower part of the screen. However, when I try to come down the ladder, the viewport won't scroll down because (I'm guessing) it doesn't have to - the viewport has another 30 pixel to go before it starts scrolling.

I tried playing around with the edges (int EdgeY) in the Smooth Scrolling script, but with no luck.
Any ideas how to make it possible to scroll back down?

dayowlron

1) the variable has to be defined outside of the function because anything defined in the function will be reset when the function is called again. When you call a function you can pass in a variable, but the value that changes in the function has to be stored when the function returns. I dont know if that helps explain it.
2) The problem I think with that code is when you call GetViewportY the value is the same from the prior call since you set the view port. Therefore when you call the function again your moving even farther up. I believe what you want is to base the viewport on the current location of the player. something closer to:
Code: ags

int yCoord = (player.y - 100); 
SetViewport(GetViewportX(),yCoord);

not sure if 100 is too much or too little but you can play around with different values
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

bulka_tarta

1) Thanks for the explanation, it definitely makes sense  (I think)!
2) I have set the yCoord to player.y - it helps with the GUI problem (the screen no longer goes up when the GUI is on), but it makes the screen jitter really badly, as well as the character appears to be moving up and down in place while moving (note, it's not animation problem, since I'm using 1 frame for up and down movement at the moment).

This topic http://www.adventuregamestudio.co.uk/forums/index.php?topic=34514.msg451054#msg451054 is the closest thing to my problem. However, there is no "Anti-Glide" mode in the setting anymore (the post is from 2008, or I just don't see it?) and the solution from the last post in the thread doesn't do anything, except for making the image flick every "counter==" frame.


Also, I found that the "int yCoord = (player.y - 100); " seems to be redundant. I simply set the line to "SetViewport(GetViewportX(), (player.y-140));" (but it gives me problem #2).
Note: This code is currently in repeatedly_execute_always, since it doesn't seem to have an effect if it's in RepExec.

Snarky

The jittering has to do with an AGS bug where it updates the character positions between when the user script runs and when it renders the screen. The way around it is to move the viewport code from repeatedly_execute_always() to the special function late_repeatedly_execute_always() (which you may have to create), which runs after the character positions have been updated. (This function was introduced in version 3.3.5, in case you're developing in an earlier version.)

Also, in future please keep it to one issue per thread. If you have multiple questions (and have searched the forums for each of them already), start multiple threads.

bulka_tarta

Thanks Snarky!
I have created the late_execute_always, and I have pasted the code over as suggested. It definitely helps, but there still seems to be some weird thing going on - the character still flickers a little when moving on x axis only. I don't think it's anything with animation, because when I set the character right in the middle of the screen, his animation looks super smooth (line 2 below). I'm guessing it's some kind of thing with AGS, where if character is moving and the camera has to follow him, it creates some sort of small distortion? To clarify, it's not as bad as before and I would call it usable, but it would be nicer if that little distortion wasn't there.

The only way I have managed to get the character anim to be smooth is with the line 2 (code below). It is a little bit hard to look at though, as character stays right in the middle of the screen, while everything else is moving.


Code: ags

  SetViewport(GetViewportX(), (player.y-140));         // has smooth-ish x, seems like it's the original AGS scroll? not sure - small flicker effect (usable)
  SetViewport((player.x-160), (player.y-140));          // no smooth scroll at all, can position character, very rigid
  SetViewport(GetViewportX(), GetViewportY());       // smooth scroll, can't position the character - small flicker effect (usable)



I think the best option is to go with line #1, but I just wanted to confirm if that's something I can still work on and it's a problem with "my" code or if it's just AGS thing that I have to get used to (the little flickering)?
Also, line 1 and 2 seems to be disabling smooth scrolling altogether. Is there a way around it or it's a trade off - either position the character where you want, or have a smooth scroll? Note: I did use cDummy for smooth scrolling before to offset the camera, but it creates a bunch of other problems.



I will keep the issues separate for the future. Sorry about that.

SMF spam blocked by CleanTalk