Avatar billede VC1 Seniormester
17. februar 2022 - 11:07 Der er 13 kommentarer og
1 løsning

Hvordan skal jeg tilgå denne form for loop vedr. image

Hej,

Jeg er ved at lave et spil i ''processing'' og her skal jeg have min baggrund til at foretage et uendeligt loop, så spillet virker uendeligt.
Jeg kan dog ikke rigtigt gennemskue hvordan min tilgang skal være, en der kan give mig et råd?
Pt. kører img fra venstre mod højre, men når framet når billedets naturlige højre ''begrænsning'' stopper billedet naturligvis sit flow.


PImage img;
int background = 0;

void setup() {
  size(1400,700);
  img = loadImage("background.jpg");
}

void draw() {
 
  image(img, background, 0);
  --background;
Avatar billede arne_v Ekspert
17. februar 2022 - 14:56 #1
Det er slet ikke klart hvad det er du vil.
Avatar billede VC1 Seniormester
17. februar 2022 - 15:12 #2
Okay, jeg prøver igen.

Jeg har et skærmvindue med et billede, dette billede rykker sig fra højre mod venstre en pixel af gangen. På et tidspunkt er billedet så langt mod venstre, at baggrunden grå kommer frem, her vil jeg gerne have billedet istedet kører en form for loop, så man får fornemmelsen af at det er 1000 billeder sat sammen der bare kører.
Avatar billede arne_v Ekspert
17. februar 2022 - 15:43 #3
Hvis vi har en tæller i, så vil:

xpos = i % WIDTH;

rulle fra venstre mod højre mens:

xpos = WIDTH + i % WIDTH + 1;

vil rulle fra højre mod venstre.
Avatar billede Henrik Hansen Forsker
17. februar 2022 - 15:45 #4
Gør selve baggrunds-billedet 2x vinduets bredte, og sørg for at indholdet i baggrundsbilledet gentager sig 2x (f.eks. samme billede fra 0-999 og fra 1000-1999)

Så kan du flytte baggrundsbilledet i vinduets bredte, og starte forfra når du når halvdelen af baggrundsbilledets bredte - resten bliver jo skjult af vinduet.
Gammelt "Sideways scroller Shooter game med parallax baggrund" trick jeg har brugt.

Baggrundsbilledets X-placering = Tæller % 1000

https://www.javatpoint.com/java-modulo
Avatar billede VC1 Seniormester
17. februar 2022 - 16:01 #5
Henrik Hansen - Tak, det lyder som en god ide, og noget jeg faktisk også selv har tænkt over, men hvordan får jeg den/dem til at fortsætte i et loop?
- Det er her jeg ikke rigtigt kan få det til at gå op i en højere mening.
Avatar billede Henrik Hansen Forsker
17. februar 2022 - 16:53 #6
Som "arne" også skriver, så laver du en tæller X (som bare tæller +1 for hver opdatering), som bruges til at udregne hvor baggrundsbilledet skal placeres.

x = (x+1) % 1000

F.eks.
x = 123. Ny x = (123+1) % 1000 = 124
x = 999. Ny x = (999+1) % 1000 = 0
x vil derfor altid være værdier mellem 0 og 999

Denne faktiske xpos skal jo egentlig være 1000 - x, da billedet skal vises fra midten til venstre side af billedet.

Jeg er ikke go' til Java, syntax'en kan være anderledes. Du har jo selv lavet det meste af kode. Tilføj noget ala

image(img, 1400 - background, 0);
background = ++background % 1400;

(billedet skal derfor være 2800pxl bredt)
Avatar billede VC1 Seniormester
17. februar 2022 - 19:15 #7
Tak for jeres input, men jeg kan simpelthen ikke få det til at fungere.

https://ibb.co/W0QnN6Q - Her er billedet som jeg prøver at matche...
Avatar billede arne_v Ekspert
17. februar 2022 - 19:20 #8
Hvordan ser din kode ud nu?
Avatar billede VC1 Seniormester
17. februar 2022 - 19:28 #9
Samme som før, jeg har prøvet at skrive Henrik's svar ind, men det skaber bare et hårdt ''flip'' mellem de to billeder, som virkelig ikke er godt at se på.

Og jeg forstår simpelthen ikke dit svar, overhovedet, så det kan jeg ikke prøve.
Avatar billede arne_v Ekspert
17. februar 2022 - 20:38 #10
Hvordan ser den komplette kode ud som du har brugt til at teste Henriks kode med?
Avatar billede VC1 Seniormester
17. februar 2022 - 20:41 #11
PImage img;

int background = 0;
int playerPosX = 45;
int playerPosY = 45;
int playerSize = 50;
int tempShotX = playerPosX;
int score = 0;
int Shots[] = new int[30];

Shots fire;

void setup() {
  size(1400,700);
  img = loadImage("background3.jpg");
  fire = new Shots();
}

void draw() {
  image(img, background, 0);
  --background; //Moving background left
  image(img, 1400 + background, 0);
  background = --background % 1000;
 
 
 
  fill(0, 100, 150);
  text("Score: "+score, 100, 50);
  textSize(25);

  drawPlayer(); //Player
  keyPressed(); //ovement
  fire.shot();  //Shoot
}



void drawPlayer(){
fill(255);
ellipse(playerPosX, playerPosY, playerSize, playerSize);
}




void keyPressed(){ //Player movement
  if (playerPosY >= 10 + (playerSize/2) && keyCode == UP){
    playerPosY = playerPosY - 5;
  }
  if (playerPosY <= 550 && keyCode == DOWN){
    playerPosY = playerPosY + 5;
  }
  if (width > playerPosX && keyCode == RIGHT){
    playerPosX = playerPosX + 5;
  }
  if (playerPosX >= 10 + (playerSize/2) && keyCode == LEFT){
    playerPosX = playerPosX - 5;
  }
/*  if (keyCode == 'b' || keyCode == 'B'){
    println(playerPosX);
  }
*/
}
Avatar billede VC1 Seniormester
17. februar 2022 - 20:41 #12
Og en class

class Shots {
int x;
int y;
int shotSize = 10;
int i = 1;


void shot(){
    if (keyCode == 'a' || keyCode == 'A'){
    Shots[i] = playerPosX;
    stroke(0);
    fill(255);
    ellipse(Shots[i], playerPosY, shotSize, shotSize); 
    Shots[i] = playerPosX+1;
   
    println(i);
     
    }
  }
}
Avatar billede Henrik Hansen Forsker
18. februar 2022 - 09:48 #13
Sørg for at dit billede er 2800px bredt (og gentager sig efter 1400px).
+ Du behøver kun "tegne" billedet 1 gang
Variablen "background" er altid positiv, når man bruger modus %. Derfor skal billedets faktiske placering udregnes derefter.
-1400 + background viser første halvdel ude for vinduet, og kører det ind mod højre efterhånden som spillet kører, for så at hoppe halv ud igen, når background igen sættes til 0 (efter 1399).
0 - background gør det bare den anden vej ... kører billedet ud af vinduets venstre side (billedets position bliver negativ).

void draw() {
  image(img, -1400 + background, 0); // Fra Venstre mod Højre
  background = ++background % 1400;


void draw() {
  image(img, 0 - background, 0); // Fra Højre mod Venstre
  background = ++background % 1400;
Avatar billede arne_v Ekspert
18. februar 2022 - 15:55 #14
Det er svært at gennemskue kodesegmenter som ikke kan køres som de er.

Her er et komplet eksempel:


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;

public class MovingFun extends JFrame {
    public class MyScroller extends JPanel {
        private static final long serialVersionUID = 1L;
        private int w;
        private int h;
        private int r;
        private int x;
        private int y;
        public MyScroller(int w, int h, int r) {
            this.w= w;
            this.h = h;
            this.r = r;
            x = w - 2 * r;
            y = h / 2 - r;
            setPreferredSize(new Dimension(w, h));   
        }
        @Override
        public void paint(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, w, h);
            g.setColor(Color.RED);
            g.fillOval(x, y, 2 * r, 2 * r);
        }
        public void move() {
            x--;
            if(x < 0) {
                x = w - 2 * r;
            }
            repaint();
        }
    }
    private static final long serialVersionUID = 1L;
    public MovingFun() {
        MyScroller mys = new MyScroller(800, 100, 25);
        JSlider js = new JSlider(JSlider.HORIZONTAL, 10, 1000, 100);
        JPanel ctl = new JPanel();
        ctl.setLayout(new GridLayout(2, 1));
        ctl.add(new JLabel("Speed:"));
        ctl.add(js);;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Moving fun");
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(mys, BorderLayout.CENTER);
        getContentPane().add(ctl, BorderLayout.SOUTH);
        pack();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    try {
                        Thread.sleep(1000 / js.getValue());
                    } catch (InterruptedException e) {
                    }
                    EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            mys.move();
                        }
                    });
                }
            }
        }).start();
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new MovingFun();
                f.setVisible(true);
            }
        });
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester