I want to create a lighting effect for my game. I did some research and I could do that by drawing a semi-transparent square and cutting out a circle or custom sprite. I looked through this tutorial here -> https://www.yoyogames.com/blog/476/quick-and-simple-lighting
My code runs, but it only shows the black screen and doesn't cut out the sprite from it. Is there something I am missing
CREATE EVENT
////////////
surface=-1;
DRAW EVENT
//////////
colortemp=draw_get_color();
cw=camera_get_view_width(view_camera[0]);
ch=camera_get_view_height(view_camera[0]);
cx=camera_get_view_x(view_camera[0]);
cy=camera_get_view_y(view_camera[0]);
if(!surface_exists(surface)){
surface=surface_create(cw,ch);
surface_set_target(surface);
draw_set_color(c_black);
draw_set_alpha(0);
draw_rectangle(0,0,cw,ch,false);
surface_reset_target();
}
if(surface_exists(surface)){
surface_set_target(surface);
//Draws the rectangle
draw_set_color(c_black);
draw_set_alpha(0.8);
draw_rectangle(0,0,cw,ch,-1);
//Draws the sprite
gpu_set_blendmode(bm_subtract);
draw_set_color(c_white);
draw_set_alpha(1);
draw_sprite_ext(light_source,0,(player.x+player.sprite_width/2),(player.y+player.sprite_height/2),1,1,0,c_white,1);
//Resets variables
gpu_set_blendmode(bm_normal);
draw_set_color(colortemp);
draw_set_alpha(1);
//resets target
surface_reset_target();
//Draws surface
draw_surface(surface,cx,cy);
//frees the screen to prevent memory leaks
if surface_exists(surface){
surface_free(surface);
}
}
Related
When a horizontal scrollview contains a VictoryChart with a brushContainer, if you activate the brush container and the horizontal scrollview at the same time it causes a crash with
ERROR TypeError: svg.getScreenCTM is not a function. (In 'svg.getScreenCTM()', 'svg.getScreenCTM' is undefined)
This case can be produced easily by using a fast single finger movement swiping horizontally over the chart
I am using ArcGIS API v4.8 and the drawing tools to draw circle on my map.
1 issue I notice is when I draw a circle, the center of the circle moves when I move my mouse resizing the circle rather than fixed at the point of the 1st mouse click starts:
How do I fix the center regardless of how I move the radius of the circle? What is missing in my code?
const options = {view, layer: tempGraphicsLayer, pointSymbol, polylineSymbol, polygonSymbol}
let sketchViewModel = new SketchViewModel(options)
let drawCircleButton = document.getElementById('circleButton')
drawCircleButton.onclick = function () {
clear()
isDrawLine = false
sketchViewModel.create('polygon', {mode: 'click'})
sketchViewModel.create('circle')
}
EDIT:
I have found a similar sample, choose the Draw Circle tool, start drawing a circle on the map, you will notice that the center of the circle moves when you move your mouse, I want it to fix the center instead.
The problem when the center moves along with your mouse move is that the circle drawn is not accurate, as I want to start with the center of the circle I want, the circle can expand outward but the center should not move.
That is because the circle, in the given example, is being draw inside the square object. Basically your start and end point are representing corners, not the center point and outer layer of the circle. So every time you expand circle object, it expands from one corner, while the rest is dragging along your mouse.
Visual example:
There are workarounds for this of course. I've made a small sample code of one of the possible ways to draw a circle from a fixed center point.
https://jsfiddle.net/wLd46g8k/9/
Basically I used an ArcGis JS API 4.x constructor called Circle, where you pass a starting point and radius. In my example I've calculated the radius from these two points.
function drawCircle(){//draws the circle
graphicsLayer.graphics.removeAll();
var graphic = new Graphic({
geometry: new Circle({//circle constructor
center: startPoint,//pass the pointer-down event X Y as a starting point
radius: Math.floor(Math.sqrt(Math.pow(startPoint.x - endPoint.x, 2) + Math.pow(startPoint.y - endPoint.y, 2)))
}), //calculates endpoint distance from the startpoint and pass it as a radius
symbol: {//circle design
type: "simple-fill",
color: "orange",
style: "solid",
outline:{
color:"darkorange",
width:4
}
}
});
graphicsLayer.graphics.add(graphic);//adds the circle
};
I'm using Canvas for drawing in my Android application. But the result has bad quality (see the picture)
So, canvas drawing don't draw additional pixels with more dark color between "stairs pixels" for smoothing.
Like this
But I'm interesting how to do it.
Are there some preferences or methods for smoothing the picture? Thanx!
Edited: I've founded here
Use the ANTI-ALIAS flag for drawing smooth edges.
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
//or
Paint p = new Paint();
p.setAntiAlias(true);
I have Button image with Rounded Button image. I am tiling image to get bigger button in QML . I am using parent as rectangle and image as BorderImage. After tiling I am getting rectangle on top image is visible. I need to remove the part of the rectangle so that only rounded button image (Has transparency) is Visible. Even i need to change the color of the behind rectangle so that Color animation is possible.
Please suggest efficient method to remove the behind rectangle and provide the color animation also.
I am attaching the Rounded button border image as attachment and source code for tiling the button image.
Rectangle{
id:outerBorderRect
smooth:true
anchors.fill:parent
//opacity:.25
//border.width:0
BorderImage{
id:innerBorderRect
smooth:true
anchors.fill:parent
border{left:20;top:16;right:17;bottom:20}
horizontalTileMode:BorderImage.Round
verticalTileMode:BorderImage.Round
source:"button_3.png"
}
}
A simple and semi-hack way to do this is to use the radius property in Rectangle to hide the corners of your button.
Or you could use a proper mask by using Qt's OpacityMask.
I'm not sure what kind of animation you're looking for. You'll have to provide more details for me to answer that part.
I've been messing around with the Graphics class to draw some things on a panel. So far to draw, I've just been using the Rectangle Structure. On a panel, by clicking a button, it makes a rectangle in a random place and adds it to an array of other rectangles (They're actually a class called UIElement, which contains a Rectangle member). When this panel is clicked, it runs a test with all the elements to see if the mouse is inside any of them, like this:
void GUIDisplay::checkCollision()
{
Point cursorLoc = Cursor::Position;
for(int a = 0; a < MAX_CONTROLS; a++)
{
if(elementList[a] != nullptr)
{
if(elementList[a]->bounds.Contains(cursorLoc))
{
elementList[a]->Select();
//MessageBox::Show("Click!", "Event");
continue;
}
elementList[a]->Deselect();
}
}
m_pDisplay->Refresh();
}
The problem is, when I click the rectangle, nothing happens.
The UIElement class draws its rectangles in the following bit of code. However, I've modified it a bit, because in this example it uses the DrawReversibleFrame method to do the actually drawing, as I was using Graphics.FillRectangle method. When I changed it, I noticed DrawReversibleFrame drew in a different place than FillRectangle. I believe this is because DrawReversibleFrame draws with its positions relative to the window, while FillRectangle does it relative to whatever Paint event its in (Mines in a panel's Paint method.) So let me just show the code:
void UIElement::render(Graphics^ g)
{
if(selected)
{
Pen^ line = gcnew Pen(Color::Black, 3);
//g->FillRectangle(gcnew SolidBrush(Color::Red), bounds);
ControlPaint::DrawReversibleFrame(bounds, SystemColors::Highlight, FrameStyle::Thick);
g->FillRectangle(gcnew SolidBrush(Color::Black), bounds);
//g->DrawLine(line, bounds.X, bounds.Y, bounds.Size.Width, bounds.Size.Height);
}
else
{
ControlPaint::DrawReversibleFrame(bounds, SystemColors::ControlDarkDark, FrameStyle::Thick);
//g->FillRectangle(gcnew SolidBrush(SystemColors::ControlDarkDark), bounds);
}
}
I add in both DrawReverisbleFrame and FillRectangle so that way I could see the difference. This is what it looked like when I clicked the frame drawn by DrawReversibleFrame:
The orange frame is where I clicked, the black is where its rendering. This shows me that the Rectangle's Contains() method is look for the rectangle relevant to the window, and not the panel. That's what I need fixed :)
I'm wondering if this is happening because the collision is tested outside of the panels Paint method. But I don't see how I could implement this collision testing inside the Paint method.
UPDATE:
Ok, so I just discovered that it appears that what DrawReversibleFrame and FillRectangle draw are always a certain distance apart. I don't quite understand this, but someone else might.
Both Cursor::Position and DrawReversableFrame operate in screen coordinates. That is for the entire screen, everything on your monitor, and not just your window. FillRectangle on the other hand operates on window coordinates, that is the position within your window.
If you take your example where you were drawing with both and the two boxes are always the same distance apart, and move your window on the screen then click again, you will see that the difference between the two boxes changes. It will be the difference between the top left corner of your window and the top left corner of the screen.
This is also why when you check to see what rectangle you clicked isn't hitting anything. You are testing the cursor position in screen coordinates against the rectangle coordinates in window space. It is possible that it would hit one of the rectangles, but it probably won't be the one you actually clicked on.
You have to always know what coordiante systems your variables are in. This is related to the original intention of Hungarian Notation which Joel Spolsky talks about in his entry Making Wrong Code Look Wrong.
Update:
PointToScreen and PointToClient should be used to convert coordinates between screen and window coordinates.