Making Sprites Detect and Sense Other Sprites

Материал из Поле цифровой дидактики
Описание Как научить спрайт определять и унюхивать другие спрайты
Область знаний Информатика, Геометрия
Область использования (ISTE)
Возрастная категория


Поясняющее видео
Близкие рецепту понятия
Среды и средства для приготовления рецепта:

This tutorial will teach how to make sprites detect and sense other sprites.

Prerequisites

The tutorial assumes users are comfortable with making projects that;

  • Use keyboard input to move sprites,
  • Send and receive broadcasts,
  • Include custom blocks and
  • Use Game Loops to control and sequence projects.

If a refresher is needed, these tutorials can be followed.

Setup

Make three variables:

(delta x)
(delta y)
(raycast result)

Make one custom block:

raycast () () () ()::custom

Make one broadcast:

broadcast (sensed v)

What Does Sprite Detection Mean?

Creating realistic characters in games starts with giving them the ability to sense their surroundings.

To make games more realistic, the sensing sprite can be created with senses. By sensing other sprites before it touches them, behaviors can be programmed so that the sensing sprite runs towards a certain sprite and away from the other sprite.

How is it Applied in Projects?

Using Sensor Edges

Some games draw invisible circles that are centered around a sprite, called sensor edges, to help implement character senses. They are as wide as the sprite can sense (hear, see or smell), and that is why it is called an edge.

When the sensor edge is touched by another sprite, the sensing sprite can react. It can run away from one sprite, or towards another.

One complication is that the sensing sprite knows when a sprite is at the edge of its senses, but it does not know in which direction. For it to know in what direction the sprites are, a second step is needed.

Casting Lines to Sense Direction and Location

This process may be called raycasting. This raycasting is when a straight line (like a ray of light) is cast in a possible direction. If the sensing sprite casts a ray in the direction it is looking (called a line of sight) and that line touches a certain sprite, the sensing sprite can process what to do based off of that information.

Putting It All Together

Using a sensor edge allows the sensing sprite to sense a sprite, then it can use raycasting to look around for a certain sprite.

How Can This be Done in Scratch?

In Scratch, the following two things need to be done.

Collision Detection and Sensor Rings

The sensor ring is a separate sprite. This sensor ring sprite can send messages to the sensing sprite whenever another sprite touches it. It also makes sure to always stay at the same position as the sensing sprite, so whenever that sprite moves, so does the sensor edge sprite. It follows the sensing sprite, and it uses the ghost effect so it is not seen by players in the game, but it still runs its code. Here is the script:

set [ghost v] effect to (100)
forever
if <touching (sprite v)?> then
	broadcast (sense v)
end
go to x: ([x position v] of (sensing sprite v)) y: ([y position v] of (sensing sprite v))
end

Casting Lines With Raycasting

When the sensing sprite receives a message (from the sensor ring sprite) telling it another sprite is close, the sensing sprite starts looking for the touching sprite. It uses trigonometry to work out the direction of the touching sprite, so it can turn away from it or, to be exact, turn 180 degrees away.

when I receive [sensed v]
raycast ([x position v] of (sprite v)) ([y position v] of (sprite v)) (0) (180)
point in direction (raycast result)
broadcast (sensed v)

define raycast (target x) (target y) (offset a) (offset b)
set [delta y v] to ((target x) - (y position))
set [delta x v] to ((target y) - (x position))
if <(delta y) = (0)> then
	if <(delta x) < (0)> then
		point in direction (-90)
	end
	else
		point in direction (90)

	if <(delta y) < (0)> then
		set [raycast result v] to ((offset a::custom) + ([atan v] of ((delta x) / (delta y)))
	else
		set [raycast result v] to ((offset b::custom) + ([atan v] of ((delta x) / (delta y)))
	end
end

External Links