I am building a video game where fireballs drop from the top screen. The spaceship, moved by controllers, must avoid those fireballs in order win. My issue is that I do not know how to detect when the spaceship collides into fireballs. However, I found this link: Detect if animated object touched another object in DOM. I analysed this code and it seems it only works for his issue particularly. Do you guys know how to do this?
Code for image spaceship and fireball:
JavaScript
x
3
1
<img src="Photo/fireball.png" id="fireball">
2
<img src="Photo/Spaceship1.png" id="icon-p">
3
Code for spaceship:
JavaScript
1
22
22
1
let rect = icon
2
let pos = {top: 1000, left: 570}
3
const keys = {}
4
window.addEventListener("keydown", function(e) {keys[e.keyCode] = true})
5
window.addEventListener("keyup", function(e) {keys[e.keyCode] = false})
6
const loop = function() {
7
if (keys[37] || keys[81]) {pos.left -= 10}
8
if (keys[39] || keys[68]) {pos.left += 10}
9
if (keys[38] || keys[90]) {pos.top -= 10}
10
if (keys[40] || keys[83]) {pos.top += 10}
11
var owidth = display.offsetWidth
12
var oheight = display.offsetHeight
13
var iwidth = rect.offsetWidth
14
var iheight = rect.offsetHeight
15
if (pos.left < 0) pos.left = -10
16
if (pos.top < 0) pos.top = -10
17
if (pos.left + iwidth >= owidth) pos.left = owidth-iwidth
18
if (pos.top + iheight >= oheight) pos.top= oheight-iheight
19
rect.setAttribute("data", owidth + ":" + oheight)
20
rect.style.left = pos.left + "px"; rect.style.top = pos.top + "px"}
21
let sens = setInterval(loop, 1000 / 60)
22
Code for fireball:
JavaScript
1
13
13
1
function fFireball(offset) {
2
return Math.floor(Math.random() * (window.innerWidth - offset))}
3
let fireballElement = document.querySelector("#fireball");
4
let fireball = {x: fFireball(fireballElement.offsetWidth), y: 0}
5
const fireLoop = function() {
6
fireball.y += 2
7
fireballElement.style.top = fireball.y + 'px'
8
if (fireball.y > window.innerHeight) {
9
fireball.x = fFireball(fireballElement.offsetWidth)
10
fireballElement.style.left = fireball.x + 'px'; fireball.y = 0}}
11
fireballElement.style.left = fireball.x + 'px'
12
let fireInterval = setInterval(fireLoop, 1000 / 100)
13
Thanks!
Advertisement
Answer
here I’ve integrated collision detection for your game. The most notable thing is in this function:
JavaScript
1
11
11
1
function checkCollision() {
2
var elem = document.getElementById("icon");
3
var elem2 = document.getElementById("fireball");
4
if ( detectOverlap(elem, elem2) && elem2.getAttribute('hit')=='false' ){
5
hits++; // detect hit and increase
6
elem2.setAttribute('hit', true); // set attribute to not have flooding
7
console.log( hits ); // console it just to see it
8
}
9
setTimeout( checkCollision, 20);
10
}
11
In lower window you can test demo that I’ve built for you without images but some random boxes as images 🙂
Good luck with game man, cool
JavaScript
1
197
197
1
//////////
2
"use strict"
3
//Stay on focus
4
function stayOnFocus() {
5
setTimeout(function() {
6
alert("Do not exit window or game progression will be lost!")
7
}, 1000)
8
}
9
10
let hits = 0
11
12
//"A" keypress plays Music
13
document.addEventListener('keydown', function(e) {
14
if (e.keyCode !== 173) {
15
//document.getElementById('audio').play()
16
}
17
})
18
19
//Input Validation
20
let icon = document.getElementById("icon")
21
let fireballElement = document.querySelector("#fireball")
22
var input = document.getElementById("input")
23
input.addEventListener("keydown", function(event) {
24
if (event.keyCode === 13) {
25
event.preventDefault();
26
document.getElementById("begin-timer").click()
27
}
28
})
29
30
//CountDown (3...2...1)
31
var count = 3
32
33
function countDown() {
34
function preventCountFast() {
35
document.getElementById("count").innerHTML = count
36
if (count > 0) {
37
count--
38
} else {
39
clearInterval(ncount);
40
document.getElementById("count").style.display = "none"
41
}
42
}
43
var ncount = setInterval(preventCountFast, 1000)
44
}
45
46
//Name displayed + space(switch between images) + parameter icon displayed
47
function Username(field) {
48
field = input.value
49
if (field == "") {
50
alert("Complete blanks");
51
return false
52
}
53
document.getElementById("askName").style.display = "none"
54
setTimeout(function() {
55
document.getElementById("name").innerHTML = "Player: " + field
56
icon.style.display = 'block';
57
fireballElement.style.display = "block"
58
const images = ["https://placehold.it/30x30", "https://placehold.it/90x90",
59
"https://placehold.it/120x40", "https://placehold.it/100x100"
60
]
61
document.body.onkeyup = function(e) {
62
if (e.keyCode === 32) {
63
hits++;
64
icon.src = images[hits % 5]
65
}
66
}
67
checkCollision();
68
}, 4000)
69
}
70
71
//Spaceship moves into space + prevent going out borders
72
let display = document.getElementById("body");
73
let rect = icon
74
let pos = {
75
top: 1000,
76
left: 570
77
}
78
const keys = {}
79
window.addEventListener("keydown", function(e) {
80
keys[e.keyCode] = true
81
})
82
window.addEventListener("keyup", function(e) {
83
keys[e.keyCode] = false
84
})
85
const loop = function() {
86
if (keys[37] || keys[81]) {
87
pos.left -= 10
88
}
89
if (keys[39] || keys[68]) {
90
pos.left += 10
91
}
92
if (keys[38] || keys[90]) {
93
pos.top -= 10
94
}
95
if (keys[40] || keys[83]) {
96
pos.top += 10
97
}
98
var owidth = display.offsetWidth
99
var oheight = display.offsetHeight
100
var iwidth = rect.offsetWidth
101
var iheight = rect.offsetHeight
102
if (pos.left < 0) pos.left = -10
103
if (pos.top < 0) pos.top = -10
104
if (pos.left + iwidth >= owidth) pos.left = owidth - iwidth
105
if (pos.top + iheight >= oheight) pos.top = oheight - iheight
106
rect.setAttribute("data", owidth + ":" + oheight)
107
rect.style.left = pos.left + "px";
108
rect.style.top = pos.top + "px"
109
}
110
let sens = setInterval(loop, 1000 / 60)
111
112
//Parameter Sensibility
113
let param = document.getElementById("parameters")
114
let b2 = document.getElementById("body2")
115
document.getElementById("general").addEventListener("click", function() {
116
param.style.display = "block";
117
b2.style.display = "none"
118
})
119
120
function validateSens() {
121
b2.style.display = "block";
122
param.style.display = "none";
123
clearInterval(sens)
124
let sensibilty = parseFloat(document.getElementById("sensibilty").value)
125
switch (sensibilty) {
126
case 1:
127
sens = setInterval(loop, 1000 / 40);
128
break;
129
case 2:
130
sens = setInterval(loop, 1000 / 60);
131
break;
132
case 3:
133
sens = setInterval(loop, 1000 / 80);
134
break;
135
default:
136
alert("Sorry, a bug occured")
137
}
138
}
139
140
//Fireball script
141
function fFireball(offset) {
142
return Math.floor(Math.random() * (window.innerWidth - offset))
143
}
144
let fireball = {
145
x: fFireball(fireballElement.offsetWidth),
146
y: 0
147
}
148
const fireLoop = function() {
149
fireball.y += 2;
150
fireballElement.style.top = fireball.y + 'px'
151
if (fireball.y > window.innerHeight) {
152
fireball.x = fFireball(fireballElement.offsetWidth)
153
fireballElement.style.left = fireball.x + 'px';
154
fireball.y = 0;
155
fireballElement.setAttribute('hit', false );
156
}
157
}
158
fireballElement.style.left = fireball.x + 'px'
159
let fireInterval = setInterval(fireLoop, 1000 / 100)
160
161
162
function checkCollision() {
163
var elem = document.getElementById("icon");
164
var elem2 = document.getElementById("fireball");
165
if (detectOverlap(elem, elem2) && elem2.getAttribute('hit')=='false' ){
166
hits++; // detect hit
167
elem2.setAttribute('hit', true);
168
aler("hi")
169
}
170
setTimeout( checkCollision, 20);
171
}
172
173
// detect fn
174
175
176
var detectOverlap = (function() {
177
function getPositions(elem) {
178
var pos = elem.getBoundingClientRect();
179
return [
180
[pos.left, pos.right],
181
[pos.top, pos.bottom]
182
];
183
}
184
185
function comparePositions(p1, p2) {
186
var r1, r2;
187
r1 = p1[0] < p2[0] ? p1 : p2;
188
r2 = p1[0] < p2[0] ? p2 : p1;
189
return r1[1] > r2[0] || r1[0] === r2[0];
190
}
191
192
return function(a, b) {
193
var pos1 = getPositions(a),
194
pos2 = getPositions(b);
195
return comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);
196
};
197
})();
JavaScript
1
158
158
1
body {
2
user-select: none;
3
margin: 0px;
4
height: 100vh;
5
padding: 0;
6
width: 100%;
7
background-image: url(Photo/bg.jpg);
8
background-repeat: no-repeat;
9
background-attachment: fixed;
10
animation: intro-fade 3s;
11
background-size: cover;
12
overflow: hidden;
13
}
14
15
#askName {
16
display: block;
17
z-index: 1;
18
margin-left: auto;
19
margin-top: 12%;
20
margin-right: auto;
21
width: 400px;
22
text-align: center;
23
background-color: #737373;
24
opacity: 0.8;
25
border-radius: 15px;
26
padding: 40px 50px 40px 50px;
27
}
28
29
#askName:hover {
30
opacity: 0.9
31
}
32
33
#askName>label {
34
text-align: center;
35
font-size: 150%;
36
font-weight: lighter;
37
text-align: center;
38
}
39
40
#askName>input {
41
display: block;
42
font-size: 100%;
43
margin: 30px auto 20px auto;
44
border: none;
45
border-radius: 10px;
46
padding: 10px 20px 10px 20px;
47
}
48
49
#askName>button {
50
background-color: #e6e6e6;
51
cursor: pointer;
52
padding: 10px 20px 10px 20px;
53
border: none;
54
border-radius: 10px;
55
}
56
57
#count {
58
margin-top: 13%;
59
animation: count-down 16s;
60
font-weight: lighter;
61
font-family: cursive;
62
text-align: center;
63
color: black;
64
font-size: 200px;
65
}
66
67
h6 {
68
margin-right: 20px;
69
padding-top: 5px;
70
font-weight: normal;
71
font-family: sans-serif;
72
margin-top: 0px;
73
color: white;
74
text-align: center;
75
font-size: 190%;
76
cursor: default;
77
}
78
79
h6:hover {
80
font-size: 210%
81
}
82
83
#icon {
84
position: absolute;
85
top: 0;
86
left: 0;
87
cursor: none;
88
width: 9%;
89
}
90
91
#general {
92
position: absolute;
93
cursor: pointer;
94
min-width: 4%;
95
top: 10px;
96
width: 4%;
97
right: 10px;
98
}
99
100
#general:hover {
101
transform: rotate(-100deg)
102
}
103
104
#parameters {
105
text-align: center;
106
display: none;
107
animation: intro-fade 3s;
108
height: auto;
109
border: none;
110
background-color: #d9d9d9;
111
color: black;
112
position: absolute;
113
padding: 0px 60px 20px 60px;
114
left: 50%;
115
width: auto;
116
min-width: 200px;
117
top: 50%;
118
transform: translate(-50%, -50%);
119
border-radius: 13px;
120
}
121
122
h3 {
123
color: black;
124
font-weight: normal;
125
font-size: 150%;
126
}
127
128
#sensibilty {
129
display: block;
130
margin-right: auto;
131
margin-left: auto;
132
}
133
134
#validateSens {
135
margin-top: 20px;
136
border: none;
137
padding: 10px;
138
border-radius: 5px;
139
cursor: pointer;
140
}
141
142
@keyframes intro-fade {
143
from {
144
opacity: 0
145
}
146
to {
147
opacity: 1
148
}
149
}
150
151
@keyframes count-down {
152
from {
153
transform: scale(0)
154
}
155
to {
156
transform: scale(1)
157
}
158
}
JavaScript
1
22
22
1
<body id="body" onload="stayOnFocus()">
2
3
<img src="https://placehold.it/350x350" id="general">
4
5
<section id="parameters">
6
<h3> Choose your sensibility </h3>
7
<input type="range" id="sensibilty" min="1" max="3" value="2">
8
<button id="validateSens" onclick="validateSens()"> Submit </button>
9
</section>
10
11
<main id="body2">
12
<form id="askName" title="Write your name"> <label> Enter your username: </label>
13
<input id="input" type="text" maxlength="10" autofocus>
14
<button type="button" onclick="countDown(); return Username()" id="begin-timer"> Submit </button>
15
</form>
16
17
<h6 id="name"></h6>
18
<h2 id="count"></h2>
19
20
<img src="https://placehold.it/50x52" id="fireball" style="display:none; width:3%; position:absolute; cursor:none">
21
<img src="https://placehold.it/80x40" id="icon" style="display:none">
22
</main>