Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.02.2018, 13:12

Javascript Kollisionsproblem

Hi :)

Ich lerne zurzeit Javascript (aktuell seit knapp einem Jahr) und verstehe auch schon die Grundlagen der Programmierung (mehr oder weniger).
Jetzt habe ich mich an ein kleines Projekt gewagt und wollte gerne ein kleines Minispiel erstellen, in dem 1 Rechteck (der Spieler) sich innerhalb einer umschlossenen Mauer bewegt und etwas einsammelt.
Ich habe bereits einen Konstruktor erstellt der die beiden Objekte beinhaltet. Damit erstelle ich den Spieler, die Mauer um ihn herum, bewege den Spieler und mache das die Kamera ihm folgt so das der Spieler zentriert wird. Mein Problem liegt aber in einer Funktion, die die Kollision zwischen Spieler und Mauer beinhaltet denn soweit habe ich es geschafft das der Spieler mit einem Rechteck kollidiert.
Das ändert sich aber wenn ich mehrere Rechtecke auf canvas zeichne denn die anderen Rechtecke scheinen keine Kollision aufzuweisen.
Hier ein Teil des Codes:


// Konstruktor für eine Box.
function Box( x, y, w, h, c )
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;

this.drawThePlayer = drawPlayer;
this.createABox = drawBox;
this.drawAFewBoxes = drawBoxes;
this.movePlayer = Move;
this.checkTheCollision = CD;
}

// 2 Instanzen des Objekts (Box).
var Player = new Box( 400, 150, 50, 50, "red" );
var Wall = new Box( 0, 0, 50, 50, "blue" );

// Hier wird die Box erstellt.
function drawBox()
{
ctx.beginPath();
ctx.rect( this.x = Wall.x, this.y = Wall.y, this.w = Wall.w, this.h = Wall.h );
ctx.fillStyle = this.c = Wall.c;
ctx.fill();
ctx.closePath();
}

// hier werden 3 Boxen auf canvas gezeichnet.
function drawBoxes()
{
for ( i = 0; i < 3; i++ )
{
Wall;
Wall.x = i * 60;

if ( Wall.x == 180 )
{
Wall.x = 0;
}

drawBox();
}
}


// am ende befindet sich die draw funktion die alles rendert.

function draw()
{
ctx.clearRect( 0, 0, canvas.width, canvas.height );
ctx.save();
ctx.translate(viewX, viewY);

drawPlayer();
drawBoxes(); // <- die 3 boxen werden mit dieser funktion gerendert.
Move();

requestAnimationFrame( draw );
ctx.restore();
}

draw();


// das hier ist pübrigens die kollision funktion.
function CD( Pobj, Wobj )
{
this.Pobj = Player;
this.Wobj = Wall;

if ( this.Pobj.y + this.Pobj.h <= this.Wobj.y )
{
return false;
}

if ( this.Pobj.y >= this.Wobj.y + this.Wobj.h )
{
return false;
}

if ( this.Pobj.x + this.Pobj.w <= this.Wobj.x )
{
return false;
}

if ( this.Pobj.x >= this.Wobj.x + this.Wobj.w )
{
return false;
}

else
{
return true;
}
}


Ich weiß nicht genau ob ich alles richtig gemacht habe aber ich zerbreche mir nun schon seit tagen den Kopf, wie ich es schaffen kann das alle 3 Boxen die Selbe Kollision aufweisen :dash: :dash: :dash:
Hat jemand in dieser Hinsicht Erfahrung oder eine Idee wie das Funktionieren könnte?
Ich würde mich über jede Hilfe sehr freuen :)

Hier ist übrigens nochmal die gesamte Datei zusammengefasst:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
var up = false;
var down = false;
var left = false;
var right = false;

var msdown = 2.0;
var msup = 2.0;
var msleft = 2.0;
var msright = 2.0;

var viewX = 0;
var viewY = 0;

var i = 0;

function keyDownHandler(e)
{
if( e.keyCode == 37 )
{
left = true;
}

if( e.keyCode == 38 )
{
up = true;
}

if ( e.keyCode == 39 )
{
right = true;
}

if( e.keyCode == 40 )
{
down = true;
}
}

function keyUpHandler(e)
{
if( e.keyCode == 37 )
{
left = false;
}

if( e.keyCode == 38 )
{
up = false;
}

if ( e.keyCode == 39 )
{
right = false;
}

if( e.keyCode == 40 )
{
down = false;
}
}

function Box( x, y, w, h, c )
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;

this.drawThePlayer = drawPlayer;
this.createABox = drawBox;
this.drawAFewBoxes = drawBoxes;
this.movePlayer = Move;
this.checkTheCollision = CD;
}

var Player = new Box( 400, 150, 50, 50, "red" );
var Wall = new Box( 0, 0, 50, 50, "blue" );

function drawPlayer()
{
ctx.beginPath();
ctx.rect( this.x = Player.x, this.y = Player.y, this.w = Player.w, this.h = Player.h );
ctx.fillStyle = this.c = Player.c;
ctx.fill();
ctx.closePath();
}

function drawBox()
{
ctx.beginPath();
ctx.rect( this.x = Wall.x, this.y = Wall.y, this.w = Wall.w, this.h = Wall.h );
ctx.fillStyle = this.c = Wall.c;
ctx.fill();
ctx.closePath();
}

function drawBoxes()
{
for ( i = 0; i < 3; i++ )
{
Wall[i];
Wall.x = i * 60;

if ( Wall.x == 180 )
{
Wall.x = 0;
}

drawBox();
}
}

function CD( Pobj, Wobj )
{
this.Pobj = Player;
this.Wobj = Wall;

if ( this.Pobj.y + this.Pobj.h <= this.Wobj.y )
{
return false;
}

if ( this.Pobj.y >= this.Wobj.y + this.Wobj.h )
{
return false;
}

if ( this.Pobj.x + this.Pobj.w <= this.Wobj.x )
{
return false;
}

if ( this.Pobj.x >= this.Wobj.x + this.Wobj.w )
{
return false;
}

else
{
return true;
}
}

function Move()
{
if ( down == true && up == false )
{
Player.y += msdown;
} if ( CD( Player, Wall[i] ) == true )
{
Player.y -= msdown;
}

if ( up == true && down == false )
{
Player.y -= msup;
} if ( CD( Player, Wall[i] ) == true )
{
Player.y += msup;
}

if ( right == true && left == false )
{
Player.x += msright;
} if ( CD( Player, Wall[i] ) == true )
{
Player.x -= msright;
}

if ( left == true && right == false )
{
Player.x -= msleft;
} if ( CD( Player, Wall[i] ) == true )
{
Player.x += msleft;
}

viewX = - Player.x + ( canvas.width / 2 ) - ( Player.w / 2 );
viewY = - Player.y + ( canvas.height / 2 ) - ( Player.h / 2 );
}

function draw()
{
ctx.clearRect( 0, 0, canvas.width, canvas.height );
ctx.save();
ctx.translate(viewX, viewY);

drawPlayer();
drawBoxes();
Move();

requestAnimationFrame( draw );
ctx.restore();
}

draw();

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Seddy« (10.02.2018, 13:56)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

10.02.2018, 13:34

Ich lerne zurzeit Java
Nur ein ganz kleiner Einwurf: Java und JavaScript sind komplett verschiedene Sprachen. Das klingt zwar nicht so, ist aber der Fall.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

10.02.2018, 13:55

Ich lerne zurzeit Java
Nur ein ganz kleiner Einwurf: Java und JavaScript sind komplett verschiedene Sprachen. Das klingt zwar nicht so, ist aber der Fall.

ah sry mein fehler hab mich verschrieben meinte javascript ^^ ja ich weiß das das beides 2 verschiedene Sprachen sind trotzdem danke :)

4

10.02.2018, 14:05

Hilft auch nur bedingt weiter: Bitte Code-Tags verwenden! ;)
fka tm

5

10.02.2018, 14:22

Hilft auch nur bedingt weiter: Bitte Code-Tags verwenden! ;)

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
var up = false;
var down = false;
var left = false;
var right = false;

var msdown = 2.0;
var msup = 2.0;
var msleft = 2.0;
var msright = 2.0;

var viewX = 0;
var viewY = 0;

var i = 0;

function keyDownHandler(e)
{
    if( e.keyCode == 37 )
        {
            left = true;
        }
    
    if( e.keyCode == 38 )
        {
            up = true;
        }
        
    if ( e.keyCode == 39 )
        {
            right = true;
        }
        
    if( e.keyCode == 40 )
        {
            down = true;
        }
}

function keyUpHandler(e)
{
    if( e.keyCode == 37 )
        {
            left = false;
        }
    
    if( e.keyCode == 38 )
        {
            up = false;
        }
        
    if ( e.keyCode == 39 )
        {
            right = false;
        }
        
    if( e.keyCode == 40 )
        {
            down = false;
        }
}

function Box( x, y, w, h, c )
{
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = c;
    
    this.drawThePlayer = drawPlayer;
    this.createABox = drawBox;
    this.drawAFewBoxes = drawBoxes;
    this.movePlayer = Move;
    this.checkTheCollision = CD;
}

var Player = new Box( 400, 150, 50, 50, "red" );
var Wall = new Box( 0, 0, 50, 50, "blue" );

function drawPlayer()
{
    ctx.beginPath();
    ctx.rect( this.x = Player.x, this.y = Player.y, this.w = Player.w, this.h = Player.h );
    ctx.fillStyle = this.c = Player.c;
    ctx.fill();
    ctx.closePath();
}

function drawBox()
{
    ctx.beginPath();
    ctx.rect( this.x = Wall.x, this.y = Wall.y, this.w = Wall.w, this.h = Wall.h );
    ctx.fillStyle = this.c = Wall.c;
    ctx.fill();
    ctx.closePath();
}

function drawBoxes()
{
    for ( i = 0; i < 3; i++ )
        {
            Wall[i];
            Wall.x = i * 60;
            
            if ( Wall.x == 180 )
                {
                    Wall.x = 0;
                }
            
            drawBox();
        }
}

function CD( Pobj, Wobj )
{
    this.Pobj = Player;
    this.Wobj = Wall;
    
    if ( this.Pobj.y + this.Pobj.h <= this.Wobj.y )
        {
            return false;
        }
    
    if ( this.Pobj.y >= this.Wobj.y + this.Wobj.h )
        {
            return false;
        }
        
    if ( this.Pobj.x + this.Pobj.w <= this.Wobj.x )
        {
            return false;
        }
        
    if ( this.Pobj.x >= this.Wobj.x + this.Wobj.w )
        {
            return false;
        }
        
    else
        {
            return true;
        }
}

function Move()
{
    if ( down == true && up == false )
        {
            Player.y += msdown;
        } if ( CD( Player, Wall[i] ) == true )
                    {
                        Player.y -= msdown;
                    }
                    
    if ( up == true && down == false )
        {
            Player.y -= msup;
        } if ( CD( Player, Wall[i] ) == true )
                    {
                        Player.y += msup;
                    }
    
    if ( right == true && left == false )
        {
            Player.x += msright;
        } if ( CD( Player, Wall[i] ) == true )
                    {
                        Player.x -= msright;
                    }
    
    if ( left == true && right == false )
        {
            Player.x -= msleft;
        } if ( CD( Player, Wall[i] ) == true )
                    {
                        Player.x += msleft;
                    }
                    
    viewX = - Player.x + ( canvas.width / 2 ) - ( Player.w / 2 );
    viewY = - Player.y + ( canvas.height / 2 ) - ( Player.h / 2 );
}

function draw()
{
    ctx.clearRect( 0, 0, canvas.width, canvas.height );
    ctx.save();
    ctx.translate(viewX, viewY);
    
    drawPlayer();
    drawBoxes();
    Move();
    
    requestAnimationFrame( draw );
    ctx.restore();
}

draw();

6

10.02.2018, 14:23

Hilft auch nur bedingt weiter: Bitte Code-Tags verwenden! ;)

ok ich sehe schon jetzt sieht das ganze wieder ganz anders aus ^^
Ist das so ok bzw. übersichtlicher oder soll ich den Code lieber aufteilen?

7

10.02.2018, 14:31

Entzückend! 8o
Hauptsache man kann es besser lesen.

Syntax-Highlighting für JavaScript fehlt hier im Forum leider noch...
fka tm

8

10.02.2018, 14:41

Entzückend! 8o
Hauptsache man kann es besser lesen.

Syntax-Highlighting für JavaScript fehlt hier im Forum leider noch...

:P
Hab auf das "#" Symbol geklickt und dann den Code dementsprechend zwischen die beiden Code-Tags eingefügt.
Da gibt es ja noch für C++ und C# aber ich dachte mir das könnte eventuell zu Fehlern im Code führen daher deswegen habe ich einfach auf # geklickt ^^

Um den Code ein wenig näher zu erläutern:

Das Hauptproblem ist für mich die Kollision.
Wenn man den Code ausführt, dann erscheinen 3 blaue Boxen links oben vom Bildschirm und eine rote in der Mitte (das ist der bewegbare Spieler).
Das rote Rechteck lässt sich mit den Pfeiltasten bewegen.
Wenn man sich nun den blauen Rechtecken nähert, dann soll bei Kontakt eine Kollision stattfinden (die Funktion hierfür habe ich CD genannt und steht für CollisionDetection).
Das Problem ist nun, das die Kollision nur mit dem 1. blauen Rechteck funktioniert aber wenn man den Spieler weiter bewegt und die beiden anderen blauen Rechtecke auf Kollision überprüft, dann stellt man fest das der Spieler durch die anderen beiden Rechtecke hindurchgeht. Aus irgendeinem Grund funktioniert dort die Kollision nicht.
Ich weiß das man eigentlich ein Array erstellen müsste um natürlich mehrere Instanzen des gleichen Objekts zu erzeugen aber wenn ich das mache, wird kein einziges Rechteck gerendert.

Habe schon vieles versucht aber leider immer noch keine Lösung gefunden :dash:

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

10.02.2018, 16:07

Nun, mit einem Debugger solltest du schnell sehen können, dass in "Move" dein "i" immer 0, bzw. nach dem ersten Durchlauf immer 2 ist. Nun denk mal darüber nach warum. Übrigens wäre es wesentlich sinnvoller die Walls, den Player und "i" entweder an Move zu übergeben oder in Move lokal zu deklarieren. Das wäre sehr viel übersichtlicher und auch viel schneller klar, dass da ein logischer Fehler vorliegt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

10

10.02.2018, 16:08

Hallo Seddy,
schön mal wieder etwas von dir zu hören ^^
Wie ich sehe beschäftigst du dich immer noch mit der Spieleprogrammierung, genauso wie ich.
Auch ich habe etwa vor 1 Jahr angefangen mich mit Javascript auseinander zusetzen.

Nun zu deinem Problem. Ich habe ein paar Kleinigkeiten entdeckt, die ich dir aufzeigen möchte:

Javascript-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Box( x, y, w, h, c )
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;

this.drawThePlayer = drawPlayer;
this.createABox = drawBox;
this.drawAFewBoxes = drawBoxes;
this.movePlayer = Move;
this.checkTheCollision = CD;
}
Hier frage ich mich, was du mit dem unteren Teil bezwecken willst?
Im Prinzip sprichst du diese Methoden ja nicht über das Objekt "Box" an.

Javascript-Quelltext

1
2
var Player = new Box( 400, 150, 50, 50, "red" );
var Wall = new Box( 0, 0, 50, 50, "blue" );
Da diese Objekte alle Rechtecke sind, kannst du die Variablen "width und height" in "size" abkürzen.

Javascript-Quelltext

1
2
3
4
5
6
7
//DrawBoxes()
Wall[i];//Ob man das auf diese Weise machen kann weiß ich nicht
...
if ( Wall.x == 180 )//Was soll das bringen?
{
Wall.x = 0;
}


Javascript-Quelltext

1
2
3
4
5
6
7
function Move()
{
if ( down == true && up == false )
{
Player.y += msdown;
} if ( CD( Player, Wall[i] ) == true )//Welchen Wert hat die Variable 'i' in diesem Augenblick?
...
Ich denke mal, dass hier das Problem liegt. Du musst hier zwischen eine for-Schleife einbauen, die 'i' inkrementiert.

Außerdem stellt sich mir die Frage, wieso du die Variablen msDown,msUp... als Gleitkommazahlen deklarierst?

Hoffentlich ich konnte dir ein wenig damit weiterhelfen, falls nicht, liegt es daran, dass ich selbst noch ein Anfänger bin :/
Ich empfehle dir, das gesamte Programm besser zu kapseln bzw. in Teilprogramme zu zerlegen, damit man sich besser zurecht findet.

Falls die Kollision immer noch nicht funktioniert, kann ich dir meine CollisionDetection Funktion, die mit Vektoren arbeitet, mitgeben, falls ich die finde.

Und Deinen Code kannst du auch mit "(js)...Code...(/js)" formatieren, nur nimmst du anstatt die Runden Klammern diese "[]".

P.s. hast du immer noch vor an JumpManiac zu arbeiten?

Werbeanzeige