tilemap collision detection not working properly on slower computers - c++

notes:
room1Collisions is a 1D array containing 1s and 0s representing collidable tiles.
+/- 0.1 is used so that the player can still move when against a collidable tile.
size is an SFML vector that holds the width and height of the player.
I understand that this code is not in great shape, but I'm trying to get collisions working to then refactor.
The issue (described below) occurs more frequently when the player collides diagonally
code:
void Player::Update(float dt) {
// 0 is a collidable tile
// change room1Collisions to a pointer of current level
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
// a is top left and b is bottom left
sf::Vector2u a(position.x/tileSize.x, (position.y+size.y/2)/tileSize.y);
sf::Vector2u b(position.x/tileSize.x, (position.y+size.y-0.1)/tileSize.y);
int tileNumberA = room1Collisions[(a.x) + a.y*(tilemapBounds.x/tileSize.x)];
int tileNumberB = room1Collisions[(b.x) + b.y*(tilemapBounds.x/tileSize.x)];
if (tileNumberA != 0 && tileNumberB != 0 && position.x >= 0) {
position.x -= speed * dt;
//animation.resumeAnimation();
}
direction = LEFT;
//animation.resumeAnimation();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
sf::Vector2u a((position.x+size.x)/tileSize.x, (position.y+size.y/2)/tileSize.y);
sf::Vector2u b((position.x+size.x)/tileSize.x, (position.y+size.y-0.1)/tileSize.y);
int tileNumberA = room1Collisions[(a.x) + a.y*(tilemapBounds.x/tileSize.x)];
int tileNumberB = room1Collisions[(b.x) + b.y*(tilemapBounds.x/tileSize.x)];
if (tileNumberA != 0 && tileNumberB != 0 && position.x+size.x <= tilemapBounds.x) {
position.x += speed * dt;
//animation.resumeAnimation();
}
direction = RIGHT;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
sf::Vector2u a((position.x+0.1)/tileSize.x, (position.y+(size.y/3))/tileSize.y);
sf::Vector2u b((position.x+size.x-0.1)/tileSize.x, (position.y+(size.y/3))/tileSize.y);
int tileNumberA = room1Collisions[(a.x) + a.y*(tilemapBounds.x/tileSize.x)];
int tileNumberB = room1Collisions[(b.x) + b.y*(tilemapBounds.x/tileSize.x)];
if (tileNumberA != 0 && tileNumberB != 0 && position.y >= 0) {
position.y -= speed * dt;
//animation.resumeAnimation();
}
direction = UP;
//animation.resumeAnimation();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
sf::Vector2u a((position.x+0.1)/tileSize.x, (position.y+size.y)/tileSize.y);
sf::Vector2u b((position.x+size.x-0.1)/tileSize.x, (position.y+size.y)/tileSize.y);
int tileNumberA = room1Collisions[(a.x) + a.y*(tilemapBounds.x/tileSize.x)];
int tileNumberB = room1Collisions[(b.x) + b.y*(tilemapBounds.x/tileSize.x)];
if (tileNumberA != 0 && tileNumberB != 0 && position.y+size.y <= tilemapBounds.y) {
position.y += speed * dt;
//animation.resumeAnimation();
}
direction = DOWN;
}
//animation.setAnimation(direction);
//animation.Update(dt, 0.2f);
//animation.setPosition(position);
box.setPosition(position);
}
The problem is that when the game is run on slower computers, sometimes the player will skip (?) a collision check and it becomes stuck in a collidable tile, preventing it from moving orthogonally with respect to the collidable tile. On faster computers this issue is not present unless the player speed (currently 30) is increased significantly.
Below is an image showing the player inside a collidable tile. Please note that in this example the player is not able to move left/right since those directions are perpendicular to the collidable tile, but can still move up.

What you need is to regulate the FPS so that it is consistent for all computers.
Frame rate regulation example(This uses the SDL2 library for SDL_GetTicks and SDL_Delay but there are probably alternatives to that depending on your graphics library):
const int FPS = 60;
const int frameDelay = 1000/FPS;
Uint32 frameStart;
int frameTime;
//Main game loop
while (true)
{
//Gets the amount of milliseconds elapsed since the program was first run
frameStart = SDL_GetTicks();
//YOUR MAIN GAME LOOP HERE
//Gets the amount of milliseconds that it took to run the game loop
frameTime = SDL_GetTicks() - frameStart;
//Checks if the game loop was run faster than the max frame time
if(frameDelay > frameTime)
{
//Delays the game loop so that it takes that the frame time always is the same
SDL_Delay(frameDelay - frameTime);
}
}
(Keep in mind that this is just an example there are lots of ways to regulate the FPS)
After implementing FPS regulation you might need to tweak the speed and collision sensitivity a little but once you have it it should be consistent on ALL computers

Related

A ball animation in simple harmonic motion using SDL2 and C++

I'm trying to emulate the following ball. Notice the simple harmonic motion of the ball, with the very ends of the ball bounce having a smaller velocity compared to the velocity in the middle:
I'm able to implement a bouncing ball, however it's not simple harmonic motion:
The corresponding code is as follows:
Dot::Dot() {
//Initialize the offsets
mPosX = 300;
mPosY = 0;
//Initialize the velocity
mVelX = 0;
mVelY = 4;
}
void Dot::move() {
//Move the dot up or down
mPosY += mVelY;
//If the dot went too far up or down
if( ( mPosY < 0 ) || ( mPosY + DOT_HEIGHT > SCREEN_HEIGHT ) )
{
//Move back
mVelY = -mVelY;
}
}
I have a simple harmonic motion model, like so:
The corresponding code is as follows:
Dot::Dot() {
//Initialize the offsets
mPosX = 300;
mPosY = 0;
//Initialize the velocity
mVelX = 0;
mVelY = 0;
}
void Dot::move() {
time_t current_time;
current_time = time(NULL);
mPosY = int(((460) - 10) * sin(2.4 * 2 * 3.141592 / 60 * current_time + (SCREEN_HEIGHT / 2)
));
//const int SCREEN_HEIGHT = 480
}
The issues with this implementation are that:
(1). the ball image appears every now and then, rather than continuously like in the blue ball model I tried to emulate at the very beginning
(2). the ball goes well beyond the top frame of the window, rather than slowing down at the very top of the window, again like the blue ball model.
For (2), I understand that I need to add a phase shift, i.e x in A*sin(wt + x), however changing this value doesn't do anything to prevent the ball from disappearing at the top of the window.
Any ideas on how to solve these issues?
Edit: I was able to solve (1) by doing += to mPosY rather than =, such as:
mPosY += int(4 * cos(2.4 * 2 * 3.141592 / 60 * current_time + (SCREEN_HEIGHT / 2) ));
However, I'm still unable to get the ball to bounce up and down within the frame of the window I created.
I recommend using actual simple harmonic equations.
For example, if your display dimensions are (500, 500), the center Y is 250. from there say your equation is in the form of x = acos(nt + m) + c where x is displacement (meters), a is amplitude n is for the period, for example the period (T) = 2PI/n t is time (seconds) and m is for phase shift and c is for the center. That way when you need the velocity of the object, you have a function that follows along the lines of
double Velocity(double time){
double vel = derivative_of_displacement_equation(time);
return vel;
}
And so in the program, you adjust the equation to suit the display dimensions, then you set the objects X/Y coordinates as the value returned from the displacement equation (PLUS THE CENTER OFFSET, in this example, if the center is at the middle of the screen, you would set the Y coordinate to the equation PLUS 250). Keep in mind coordinates begin at (0,0) so your displacement equation (at least the part where it involves the proportional factor, which in this case is time), you make that negative instead.
Here is some code that I believe answers your question:
#include <SDL2/SDL.h>
#include <chrono>
#include <math.h>
#include <iostream>
const double PI = 3.14159265358979;
void draw_circle(SDL_Renderer *renderer, int x, int y, int radius, SDL_Color color)
{
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
for (int w = 0; w < radius * 2; w++)
{
for (int h = 0; h < radius * 2; h++)
{
int dx = radius - w; // horizontal offset
int dy = radius - h; // vertical offset
if ((dx*dx + dy*dy) <= (radius * radius))
{
SDL_RenderDrawPoint(renderer, x + dx, y + dy);
}
}
}
}
double Displacement(double time, double a, double n, double m, double c)
{
double displacement = a*cos(n*time + m) + c;
return displacement;
}
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("SHM", 0, 30, 500, 500, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);// | SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED );
double timeDifference;
std::chrono::steady_clock::time_point start, finish;
start = std::chrono::steady_clock::now();
finish = start;
SDL_Event event;
bool running = true;
while (running){
while (SDL_PollEvent(&event)){
if (event.type == SDL_QUIT){
running = false;
break;
}
}
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
SDL_RenderClear(renderer);
finish = std::chrono::steady_clock::now();
timeDifference = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
timeDifference = timeDifference / 1000000000;
///The "-(250-20) is the center y (250) minus the radius of the circle (20), and its - out the front as negative a due to coordinates
double yPosition = round( Displacement(timeDifference, -(250-20), 2, 0, 250 ) );
draw_circle(renderer, 250, yPosition, 20, {255,0,0});
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
In general you have a0 + a/2*cos (2*𝝥*t/T + 𝝫) where a0 is the vertical position of the half of the vertical travel, a is the height of the travel, t is time, T the period ie., the time to do a complete cycle for going and coming back to the same state or uple { position, momentum }, and 𝝫 the time shift, ie., the moment where the height is at zero of the cos.
So if you want the ball to be on the floor at t=0, you want cos at the minimum, ie., 𝝫 = -𝝥/2.
You want to manage your position in function of your game's time t, so you can decouple the time to compute (which depend on your compute calpabilities) and the game's time (that you want constant from a machine to another).
Therefore you want:
auto VerticalPosition(double t)
-> double { return CorrectedScreenHeight/2*(1 + cos(2*PI*t/T + phi)); }
And you define CorrectedScreenHeight = SCREEN_HEIGHT - DOT_HEIGHT, T and phi outside, as properties of your system.
Between two consecutive images, you increment t, in order to have the correct experienced time. Typically you have 60 images/s (WPF, DirectX, web, etc), hence a period of 1.0/60s between consecutive images, this goes in your function that modifies t. The speed of your ball then depend on T, that you can tune independently.

interpolation in application causes sprite to jitter

I wanted to implement a special Game loop where the game actually only updates 25 frames a second while it is rendered at the top speed of the computer. I followed the article from dewitters game loop and have the interpolation setup correctly i believe (btw i'm using sdl2)...
const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;
Uint32 next_game_tick = SDL_GetTicks();
int loops;
float interpolation;
while (running)
{
loops = 0;
while (SDL_GetTicks() > next_game_tick && loops < MAX_FRAMESKIP)
{
Update();
next_game_tick += SKIP_TICKS;
loops++;
}
interpolation = float(SDL_GetTicks() + SKIP_TICKS - next_game_tick) / float(SKIP_TICKS);
Render(interpolation);
}
But I don't really understand how to implement the interpolation within the render call. i tried just setting the x and y position of my sprite relative to the interpolation...
interPos.x = pos.x + int (speed * interpolation);
interPos.y = pos.y + int (speed * interpolation);
link.Draw(ren, interPos, 0, false);
but this just made the main character sprite jitter all around. Any help appreciated!

SFML 2.1 how to make one sprite face another sprite

I am trying to make a shooter game, and while trying to code the enemies
to face towards the player, I tried to use trigonometry to find the necessary rotation, but the code didn't work, and the enemy rotated erratically. This is the code:
void face(sf::Sprite& target, sf::Sprite& subject){
int adjacent = subject.getPosition().x - target.getPosition().x;
int opposite = target.getPosition().y - subject.getPosition().y;
if (opposite == 0){
opposite++;
}
if (adjacent == 0){
adjacent++;
}
//if (adjacent < 0){
//adjacent += 180;
//}
float result=atan(/*opposite / adjacent*/adjacent/opposite)*180/PI;
subject.setRotation(result);
}
Any advice would be appreciated!
You must use float with adjacent and opposite. And change result with this:
float angle = atan(adjacent / opposite) * 180 / PI;
if (opposite > 0)
angle += 180;

C++ SFML collision is not accurate

I'm making a 2D game with SFML in C++ and I have a problem with collision. I have a player and a map made of tiles. Thing that doesn't work is that my collision detection is not accurate. When I move player up and then down towards tiles, it ends up differently.
I am aware that source of this problem may be calculating player movement with use of delta time between frames - so it is not constant. But it smooths movement, so I don't know how to do it other way. I tried with constant speed valuses and to make collision fully accurate - speed had to be very low and I am not satisfied with that.
void Player::move() {
sf::Vector2f offsetVec;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
offsetVec += sf::Vector2f(0, -10);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
offsetVec += sf::Vector2f(0, 10);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
offsetVec += sf::Vector2f(-10, 0);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
offsetVec += sf::Vector2f(10, 0);
this->moveVec += offsetVec;
}
void Player::update(float dt, Map *map) {
sf::Vector2f offset = sf::Vector2f(this->moveVec.x * this->playerSpeed * dt,
this->moveVec.y * this->playerSpeed * dt);
sf::Sprite futurePos = this->sprite;
futurePos.move(offset);
if (map->isCollideable(this->pos.x, this->pos.y, futurePos.getGlobalBounds())) {
this->moveVec = sf::Vector2f(0, 0);
return;
}
this->sprite.move(offset);
this->pos += offset;
this->moveVec = sf::Vector2f(0, 0);
return;
}
In player position update I create future sprite object, which is object after applying movement, to get it's boundaries and pass it to collision checker. To collision checker I also pass player pos, because my map is stored in 2d array of tile pointers, so I check only these in player range.
bool Map::isCollideable(float x, float y, const sf::FloatRect &playerBounds) {
int startX = int(x) / Storage::tileSize;
int startY = int(y) / Storage::tileSize;
Tile *tile;
for (int i = startX - 10; i <= startX + 10; ++i) {
for (int j = startY - 10; j <= startY + 10; ++j) {
if (i >= 0 && j >= 0) {
tile = getTile(i, j);
if (tile != nullptr && playerBounds.intersects(tile->getGlobalBounds()))
return true;
}
}
}
return false;
}
Full project on Github
My solution
I have changed if statement in update function to while statement, which decreases my offset vector till no collision is present. I still have to make some adjustments, but general idea is:
void Player::update(float dt, Map *map) {
int repeats = 0;
sf::Vector2f offset = sf::Vector2f(this->moveVec.x * this->playerSpeed * dt,
this->moveVec.y * this->playerSpeed * dt);
sf::Sprite futurePos = this->sprite;
while (map->isCollideable(this->pos.x, this->pos.y, futurePos, offset)) {
offset = 0.7f * offset;
repeats++;
if (repeats > 5) {
this->moveVec = sf::Vector2f(0, 0);
return;
}
}
this->sprite.move(offset);
this->pos += offset;
this->moveVec = sf::Vector2f(0, 0);
return;
}
I also had to rework isCollideable method a little, so it accepts sf::Sprite and offset vector so it can calculate boundaries on it's own.
When the player collides with a tile, you should calculate the penetration, that is, the value of "how much the player went into the tile". When you have this value, nudge your player back that much.
This is just a thought but you could have some inaccuracies in your collision detection when you typecast the float x, and y to integers and then divide them. This could cause problems because some of the data in the float could be lost. If the float was 3.5 or 3.3 or 3.9 then it would become 3 which throws off your collision calculations.

2D water shader in SFML

I want to implement the algorithm for a 2D water surface described here and here.
But instead of using two int arrays and calculating on the CPU I would like to use SFML's sf::RenderTexture's (FBO's basically) and a GLSL shader to run everything on the GPU. I want to use SFML, because it's so simple and I have worked with it before, so I know my way around it a little.
I've made some good progress so far. I was able to set up 3 sf::RenderTextures and ping-pong between them correctly (because other than int array you can't read and write to the same sf::RenderTexture at the same time). I was also able to adapt the algorithm for the height field creation form being in the range -32.767 to 32.767 to the range 0 to 1 (or to be more precise -0.5 to 0.5 for the calculation). Also adding new ripples works to some extend. So up to this point you can actually see a little of waves going on.
Here comes my problem now: The waves disappear really, really fast and I don't even apply any damping yet. According to the algorithm the ripples are not stopping if there is no damping applied. It's even the other way around. If I apply "amplification" the waves look close to what you would expect them to look like (but they still disappear without any damping applied to them). My first thought was that this is, because I use float's in range 0 - 1 instead of integers, but I only see this being a problem if multiplication is used, but I only use addition and subtraction.
Here is my SFML C++ code :
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(1000, 1000), "SFML works!");
window.setFramerateLimit(12);
sf::RenderTexture buffers[3];
buffers[0].create(500, 500);
buffers[1].create(500, 500);
buffers[2].create(500, 500);
sf::RenderTexture* firstBuffer = buffers;
sf::RenderTexture* secondBuffer = &buffers[1];
sf::RenderTexture* finalBuffer = &buffers[2];
firstBuffer->clear(sf::Color(128, 128, 128));
secondBuffer->clear(sf::Color(128, 128, 128));
finalBuffer->clear(sf::Color(128, 128, 128));
sf::Shader waterHeightmapShader;
waterHeightmapShader.loadFromFile("waterHeightmapShader.glsl", sf::Shader::Fragment);
sf::Sprite spritefirst;
spritefirst.setPosition(0, 0);
spritefirst.setTexture(firstBuffer->getTexture());
sf::Sprite spritesecond;
spritesecond.setPosition(500, 0);
spritesecond.setTexture(secondBuffer->getTexture());
sf::Sprite spritefinal;
spritefinal.setPosition(0, 500);
spritefinal.setTexture(finalBuffer->getTexture());
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Escape)
window.close();
}
waterHeightmapShader.setParameter("mousePosition", sf::Vector2f(-1.f, -1.f));
// if mouse button is pressed add new ripples
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(window);
if(mousePosition.x < 500 && mousePosition.y < 500)
{
sf::Vector2f mouse(mousePosition);
mouse.x /= 500.f;
mouse.y /= 500.f;
mouse.y = 1 - mouse.y;
std::cout << mouse.x << " " << mouse.y << std::endl;
waterHeightmapShader.setParameter("mousePosition", mouse);
}
}
waterHeightmapShader.setParameter("textureTwoFramesAgo", firstBuffer->getTexture());
waterHeightmapShader.setParameter("textureOneFrameAgo", secondBuffer->getTexture());
// create the heightmap
secondBuffer->display();
finalBuffer->clear(sf::Color(128, 128, 128));
finalBuffer->draw(sf::Sprite(secondBuffer->getTexture()), &waterHeightmapShader);
finalBuffer->display();
spritefirst.setTexture(firstBuffer->getTexture());
spritesecond.setTexture(secondBuffer->getTexture());
spritefinal.setTexture(finalBuffer->getTexture());
window.clear();
window.draw(spritefirst);
window.draw(spritesecond);
window.draw(spritefinal);
window.display();
// swap the buffers around, first becomes second, second becomes third and third becomes first
sf::RenderTexture* swapper = firstBuffer;
firstBuffer = secondBuffer;
secondBuffer = finalBuffer;
finalBuffer = swapper;
}
return 0;
}
And here is my GLSL shader code :
uniform sampler2D textureTwoFramesAgo;
uniform sampler2D textureOneFrameAgo;
uniform vec2 mousePosition;
const float textureSize = 500.0;
const float pixelSize = 1.0 / textureSize;
void main()
{
// pixels position
vec2 position = gl_TexCoord[0].st;
vec4 finalColor = ((texture2D(textureOneFrameAgo, vec2(position.x - pixelSize, position.y)) +
texture2D(textureOneFrameAgo, vec2(position.x + pixelSize, position.y)) +
texture2D(textureOneFrameAgo, vec2(position.x, position.y + pixelSize)) +
texture2D(textureOneFrameAgo, vec2(position.x, position.y - pixelSize)) - 2.0) / 2) -
(texture2D(textureTwoFramesAgo, position) - 0.5);
// damping
// finalColor.rgb *= 1.9; // <---- uncomment this for the "amplifiction" ie. to see the waves better
finalColor.rgb += 0.5;
// add new ripples
if(mousePosition.x > 0.0)
{
if(distance(position, mousePosition) < pixelSize * 5)
{
finalColor = vec4(0.9, 0.9, 0.9, 1.0);
}
}
gl_FragColor = finalColor;
}
Please remember that this is all just about the height field creation. There is no shading of the water yet.
Do you know why the waves disappear by them self without damping?
If I am reading the code correctly you sample the previous frame for the texture's colors/height and use four neighboring pixels/texels to determine the color/height of the current pixel.
As you are calculating (scaling) these neighbors you might run into missing the texel that contains the color/height you are looking for. It might not be the heighest texel, just one next to it a little bit lower causing the unexpected damping.
This is where you do not just use addition and subtraction:
const float pixelSize = 1.0 / textureSize;
By using this value you could just miss the texel you are looking for.
EDIT
Also: you are averaging the samples so the result will always be less than the maximum value of the samples. So instead of averaging you could select the maximum value. That might give weird results but also extra insight.
Here are some "Processing" codes which implements the same algorithm you've posted above, and its damping is correct, I hope you can get some points from it :
// codes begin
int Width = 800;
int Height = 600;
int FullSize = 0;
//int Spacing = 10;
int[] source, dest;
PImage bg;
void setup()
{
// if you want to run these codes by "Processing"
// please make a picture named "HelloWorld.png"
bg = loadImage("HelloWorld.png");
Width = bg.width;
Height = bg.height;
FullSize = Width * Height;
size(Width, Height);
source = new int[FullSize];
dest = new int[FullSize];
for (int i=0; i< FullSize; i++)
source[i] = dest[i] = 0;
}
void draw()
{
for (int i=Width; i< FullSize-Width; i++)
{
// check for bounds
int xi = i % Width;
if ((xi==0) || (xi==Width-1)) continue;
dest[i] = (
((source[i-1]+
source[i+1]+
source[i-Width]+
source[i+Width]) >>1) ) -dest[i];
int dampFactor = 1000;
dest[i] -= (dest[i] >> dampFactor); // Damping - Quick divde by 32 (5 bits)
}
//image(bg, 0, 0);
loadPixels();
for (int i=Width; i< FullSize-Width; i++)
{
// check for bounds
int xi = i % Width;
if ((xi==0) || (xi==Width-1)) continue;
int xoffset = dest[i-1] - dest[i+1];
int yoffset = dest[i-Width] - dest[i+Width];
int offset = i+xoffset+yoffset*Width;
if (offset>0 && offset<FullSize)
{
// TODO: make better map
pixels[i] = bg.pixels[offset];
}
}
//bg.updatePixels();
updatePixels();
//swap
int[] temp = source;
source = dest;
dest = temp;
}
void mouseDragged()
{
if (mouseX > 0 && mouseX < Width && mouseY > 0 && mouseY < Height)
source[mouseY*Width+mouseX] = (int)random(50, 100);
}
void mousePressed()
{
// TODO: make a area pulse value, like a radius circle
if (mouseX > 0 && mouseX < Width && mouseY > 0 && mouseY < Height)
source[mouseY*Width+mouseX] = (int)random(50, 100);
}
// codes end